Problem:
Problem E: The Number of the Real Roots of a Cubic Equation

Description

3次方程式： が与えられるので，その正の実数根の個数，負の実数根の個数をそれぞれ調べて欲しい．

根の個数は，重根も含めて数えるものとする．

Input

入力は複数のテストケースからなり，1行目にはその個数が記される．

2行目以降はa b c dの形式で3次方程式の係数が記される．aは0ではなく，またそれぞれの数は-100から100までの整数値である．

Output

与えられた3次方程式に対し，正の実数根の個数，負の実数根の個数をスペースで区切って出力せよ．

Sample Input

2
1 3 3 1
-10 0 0 0

Output for Sample Input

0 3
0 0

Solution in JAVA (judge verdict: Wrong Answer)


import java.io.*;
import java.util.*;


// 2011/10/20

//@2220 Rûö®
public class Main {

	
	// C return falseÅ¨µÜ¢
	boolean main() throws IOException {

		int[] ir = readIntArray();
		double a = ir[0];
		double b = ir[1];
		double c = ir[2];
		double d = ir[3];
		
		if (a < 0) {
			a = -a;
			b = -b;
			c = -c;
			d = -d;
		}
		
		// ÷ªQ®
		double a2 = 3 * a;
		double b2 = 2 * b;
		double c2 = c;
		
		int kaiCntP = 0; // ³ÌðÌ
		int kaiCntN = 0; // ÌðÌ

		
		// »Ê®
		double d2 = b2 * b2 - 4 * a2 * c2;
		
		if (d2 > 0) {
			double kai1 = (-b2 + Math.sqrt(d2)) / (2 * a2);
			double kai2 = (-b2 + Math.sqrt(d2)) / (2 * a2);
			double y1 = a * kai1 * kai1 * kai1 + b * kai1 * kai1 + c * kai1 + d; 
			double y2 = a * kai2 * kai2 * kai2 + b * kai2 * kai2 + c * kai2 + d;
			if (y1 > 0 && y2 > 0) {
				if (d > 0) {
					kaiCntN = 1;
				}
				else {
					kaiCntP = 1;
				}
				// d=0 Í0 0
			}
			else if (y1 < 0 && y2 < 0) {
				if (d > 0) {
					kaiCntN = 1;
				}
				else {
					kaiCntP = 1;
				}
				// d=0 Í0 0
			}
			else {
				// 3ÂÌÙÈéðª éI
				assert y1 > y2;
				if (kai1 >= 0) {
					if (d > 0) {
						kaiCntP = 2;
						kaiCntN = 1;
					}
					else if (d < 0) {
						kaiCntP = 3;
					}
					else {
						kaiCntP = 2;
					}
				}
				else if (kai2 <= 0) {
					if (d > 0) {
						kaiCntN = 3;
					}
					else if (d < 0) {
						kaiCntP = 1;
						kaiCntN = 2;
					}
					else {
						kaiCntN = 2;
					}
				}
				else {
					if (d > 0) {
						kaiCntP = 2;
						kaiCntN = 1;
					}
					else if (d < 0) {
						kaiCntP = 1;
						kaiCntN = 2;
					}
					else {
						kaiCntP = 1;
						kaiCntN = 1;
					}
				}
			}
		}
		else if (d2 == 0) {
			double kai = -b2 / (2 * a2);
			double y = a * kai * kai * kai + b * kai * kai + c * kai + d; 
			if (y == 0) { // 3d_ªx²ã
				// 3dð
				if (kai > 0) {
					kaiCntP = 3;
				}
				else if (kai < 0) {
					kaiCntN = 3;
				}
			}
			else {
				if (d > 0) {
					kaiCntN = 1;
				}
				else {
					kaiCntP = 1;
				}
				// d=0 Í0 0
			}
		}
		else { // d2 < 0
			if (d > 0) {
				kaiCntN = 1;
			}
			else {
				kaiCntP = 1;
			}
			// d=0 Í0 0
		}
				
		// ðÌ\¦
		System.out.printf("%d %d", kaiCntP, kaiCntN);
		
		
//		return true; // ³íI¹ Ö
		return false;
	}
	

//	private final static boolean DEBUG = true;  // debug
	private final static boolean DEBUG = false; // release

	public static void main(String[] args) throws IOException {

		if (DEBUG) {
			log = System.out;
			
			String inputStr = "1\n-10 0 0 0\n";
			reader = new BufferedReader(new StringReader(inputStr)); 

		}
		else {
			log = new PrintStream(new OutputStream() { public void write(int b) {} } ); // «ÌÄ
			reader = new BufferedReader(new InputStreamReader(System.in)); // R\[©ç
		}
		
		int N = readIntArray()[0];

		for(int i = 0; i < N; i++) {
			boolean b = new Main().main();
			if (!b)
				break;
		}		
		
		reader.close();
	}

	
	static PrintStream log;
	static BufferedReader reader;
	

	// WüÍæè1sªÌXy[XæØèÌ®lðÇÞ
	// EOFÌêÍnullðÔ·
	private static int[] readIntArray() throws IOException {
		
		String s = reader.readLine();
		if (s == null)
			return null;
		String[] sp = s.split(" ");
		int[] a = new int[sp.length];
		for(int i = 0; i < sp.length; i++) {
			a[i] = Integer.parseInt(sp[i]);
		}
		return a;
	}
		
}