41 / 83
Oct 2014

I have adapted a solution that seemed fine to me that was posted several years ago. When I tested it in an IDE I noticed that the PrintWriter caused the program to store the outputs until the end command "42" was reached. I then changed writer.println(s) to System.out.println(s) and indeed now the input was also returned as output immediately after pressing Enter. However, I still got a runtime error. Then, I changed int N = nextInt(); to String s = nextToken();. Still a runtime error. However, I now have found out that for some reason I cannot input strings, even though the nextToken() method returns tokenizer.nextToken().

Can anybody explain why the code below results in an NZEC runtime error? Keep in mind that the outputs are displayed after every input (which is commonly not the case for the NZEC runtime errors with this problem). I also don't know why my outputs are supposedly displayed "properly", as I don't see the difference between writer.println() and System.out.println(). Then I also wonder why I get an error whenever I input a string that is strictly not also a numeric value.

Any help would be appreciated! wink

/*
 * 
 * Date: 01-10-2014
 * Problem Statement link: http://www.spoj.com/problems/TEST/
 * Main site of P.S.: http://www.spoj.com/
 * 
 * Task name: TEST
 */
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
// import java.math.*;
import java.util.*;
public class Main
{
   private void solve() throws IOException
   {
      for (; ; )
      {
         String s = nextToken();
         if (Integer.parseInt(s) == 42)
            break;
         System.out.println(s);
      }
   }
   public static void main(String arg[])
   {
      new Main().run();
   }
   BufferedReader reader;
   StringTokenizer tokenizer;
   PrintWriter writer;
   public void run()
   {
      try
      {
         reader = new BufferedReader(new InputStreamReader(System.in));
         tokenizer = null;
         writer = new PrintWriter(System.out);
         solve();
         reader.close();
         writer.close();
         // System.exit(0); // MUST INCLUDE THIS; VITAL FOR SUBMISSION TO SPOJ
      }
      catch (Exception e)
      {
         e.printStackTrace();
         System.exit(1);
      }
   }
   int nextInt() throws IOException
   {
      return Integer.parseInt(nextToken());
   }
   long nextLong() throws IOException
   {
      return Long.parseLong(nextToken());
   }
   double nextDouble() throws IOException
   {
      return Double.parseDouble(nextToken());
   }
   String nextToken() throws IOException
   {
      while (tokenizer == null || !tokenizer.hasMoreTokens())
      {
         tokenizer = new StringTokenizer(reader.readLine());
      }
      return tokenizer.nextToken();
   }
}

The behaviour you're seeing of output being printed immediately after input is normal.

The console is complicated in this regard because it both receives input from Sydtem.in and prints whatever arrives on System.out. As long as what you write to System.out is correct then that is ok.

A common practice is to redirect input and output to files for local testing so that you are not dealing with the console.

[EDIT: this post was written before leppy's response. I thought I submitted this post but somehow it did not appear on the forum. The last sentence now doesn't apply anymore but imagine that chronologically I wrote this before leppy's response!]

[EDIT #2: I tested both closing and not closing the reader using System.exit(0) and not using it. In all cases System.exit(0) gave the exact same results as not using System.exit(0).]

My question about why things work the way they do (strings give an error even though String s = nextToken() is used, writer stores its data and releases it all at once instead of after every input). However, I have now found the part of my code and the code posted by Token several years ago, that was causing the issue.
For some reason, after not using the PrintWriter altogether, there was only one more thing causing the NZEC runtime error. Commenting out the line of code that closes the BufferedReader,

reader.close();

, instantly fixed the error and made SPOJ accept my program (that is, the one I used, which was created by Token, not me).

I'm relieved that things are working now for some unknown reason, but I'd still really appreciate to hear from anyone why these things work so strangely!

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
// import java.io.PrintWriter;
// import java.math.*;
// import java.util.*;
import java.util.StringTokenizer;
public class Main
{
   private void solve() throws IOException
   {
      for (; ; )
      {
         int N = nextInt();
         if (N == 42)
            break;
         System.out.println(N);
      }
   }
   public static void main(String arg[])
   {
      new Main().run();
   }
   BufferedReader reader;
   StringTokenizer tokenizer;
   // PrintWriter writer;
   public void run()
   {
      try
      {
         reader = new BufferedReader(new InputStreamReader(System.in));
         tokenizer = null;
         // writer = new PrintWriter(System.out);
         solve();
         // reader.close();
         // writer.close();
      }
      catch (Exception e)
      {
         e.printStackTrace();
         System.exit(1);
      }
   }
   int nextInt() throws IOException
   {
      return Integer.parseInt(nextToken());
   }
   long nextLong() throws IOException
   {
      return Long.parseLong(nextToken());
   }
   double nextDouble() throws IOException
   {
      return Double.parseDouble(nextToken());
   }
   String nextToken() throws IOException
   {
      while (tokenizer == null || !tokenizer.hasMoreTokens())
      {
         tokenizer = new StringTokenizer(reader.readLine());
      }
      return tokenizer.nextToken();
   }
}

PrintWriter: docs.oracle.com/javase/7/docs/ap ... riter.html14

PrintWriter does not automatically flush out to System.out. This is why you don't see it output as you go.

Why reader.close() causes NZEC is a mystery to me. Maybe SPOJ won't allow you to close System.out.

Your questions sort of ramble, so I might have missed some details. If you have any other questions, please continue to post.

10 months later

kindly change your program .. its totally wrong !!!
if input 4200 then it wont print it .... but logically it should as its not equal 42 bt according to ur logic as it starts with 42 so it doesnt prints ... it sucks big time smiling_imp imp !!!!

Próbowałem ze wszystkimi (double, long double i float)

To naprawdę proste zadanko, zero haczyków, PI używasz tego co podali, zwykłe double i wszystko jest cacy.

a to nie to samo co O(min(n,m)) ? 8)

9 months later

komentarz do rozwiązania linxaddict

nie wiem dlaczego daje błedne odpowiedzi, nie chciało mi się testować ani dokładnie analizować bo kod za długi

może warto dodać na końcu 'return 0;' ?

a kod zbyt długi bo:

po co wczytywać wszystkie testy do pamięci ?
wystarczy pojedyńczo

po co dynamicznie allokować tablicę ?
znamy maksymalny rozmiar

po co pisać własnego quicksorta ?
jest qsort, wystarczy napisać funkcję porównania

po co taka dziwna sekwencja:

for(int i = 0; i < t; ++i) {
for(int j = 0; j < n[i]; ++j)
quicksort(tab[i], 0, j);

wystarczy tylko jedna pętla (chyba że to nie jest quicksort)

po co używać po obu stronach porównania sqrt ?
tylko narzut na czas wykonania

po co używać pow
lepiej zwykłego mnożenia

po co wyliczać d w każdym porównaniu
przecież można policzyć raz w czasie czytania danych i zapamietać

rzeczywiście, pierwszy błąd (char name[10]wink może dawać błędne wyniki,
drugi jest nieistotny, w tym przypadku & nie ma znaczenia.

prawdziwy problem jest w błednej implementacji quicksorta, daja całkowite bzdury, sprawdź dla danych:

1
100
A100 0 100
A99 0 99
A98 0 98
...
A01 0 1

Napisałem więc od nowa... i znów rozwiązanie nie jest akceptowane. Gdzie popełniam błąd? Oto kod:

#include <iostream>
#include <cstdlib>
#include <cmath>
#include <cstring>
using namespace std;
struct Point {
	char name[11];
	int x;
	int y;
};
int compare(const void *v1, const void *v2) {
	Point *p1 = (Point*)(v1);
	Point *p2 = (Point*)(v2);
	if(sqrt(p1->x*p1->x + p1->y*p1->y) < sqrt(p2->x*p2->x + p2->x*p2->y)) return -1;
	if(sqrt(p1->x*p1->x + p1->y*p1->y) > sqrt(p2->x*p2->x + p2->x*p2->y)) return 1;
	else return 0;
}
int main() {
	unsigned t;
	cin >> t;
	Point tab[1000];
	unsigned n;
    for(int i = 0; i < t; ++i) {
	cin >> n;
	for(int j = 0; j < n; ++j) {
		cin >> tab[j].name;
		if(strlen(tab[j].name) > 10) return 1;
		cin >> tab[j].x;
		if(tab[j].x < -1000 || tab[j].x > 1000) return 1;
		cin >> tab[j].y;
		if(tab[j].y < -1000 || tab[j].y > 1000) return 1;
	}

	qsort(tab, n, sizeof(Point), compare);

	for(int j = 0; j < n; ++j)
		cout << tab[j].name << " " << tab[j].x << " " << tab[j].y << endl;
	cout << endl;
}

return 0;
}

Imho tutaj:

sqrt(p2->x*p2->x + p2->x*p2->y)

powinno być chyba

sqrt(p2->x*p2->x + p2->y*p2->y)

już prawie dobrze, choć było by lepiej zamiast:

int compare(const void *v1, const void *v2) {
	Point *p1 = (Point*)(v1);
	Point *p2 = (Point*)(v2);
	if(sqrt(p1->x*p1->x + p1->y*p1->y) < sqrt(p2->x*p2->x + p2->x*p2->y)) return -1;
	if(sqrt(p1->x*p1->x + p1->y*p1->y) > sqrt(p2->x*p2->x + p2->x*p2->y)) return 1;
	else return 0;
}

napisać znacznie prościej (bo sqrt jest niepotrzebny, a dwa razy liczyć też nie trzeba):

int compare(const void *v1, const void *v2) {
	Point *p1 = (Point*)(v1);
	Point *p2 = (Point*)(v2);
	int d = (p1->x*p1->x + p1->y*p1->y) - (p2->x*p2->x + p2->y*p2->y);
	return d;
}

a jeszcze lepiej dodać do struktury d i wyliczać po wczytaniu x i y, wtedy funkcja porównująca jest jeszcze prostsza.

7 months later

Mógłby ktoś znaleźć błąd, bo dla wszystkich danych jakie spr wychodziło dobrze, a dostaję błędną odpowiedź.

#include <iostream>
#include <string>
using namespace std;
unsigned long long int odleglosc(long long int, long long int);
int main()
{
    long long int t, n, x[100], y[100];
    string nazwa[100];
    cin >> t;
    while(t--)
    {
        cin >> n;
        for(int i=0; i<n; i++) 
        {
            cin >> nazwa[i] >> x[i] >> y[i];
        }
        for(int i=0; i<n-1; i++)
        {
            for(int j=1; j<n; j++)
            {
                if(odleglosc(x[i],y[i])>odleglosc(x[j],y[j]))
                {
                   swap(nazwa[i], nazwa[j]);
                   swap(x[i], x[j]);
                   swap(y[i], y[j]);
                }
            }
        }
        for(int i=0; i<n; i++) cout << nazwa[i] << " " << x[i] << " " << y[i] << "\n";
        cout << "\n";
    }
    return 0;
}
unsigned long long int odleglosc(long long int x, long long int y)
{
       unsigned long long int d;
       d=x*x+y*y;
       return d;
}
11 months later

Mam problem, ponieważ rozwiązanie, które napisałem wygląda na poprawne (nie znalazłem danych przy których odpowiedz byłaby błędna), ale niestety tester nie chce go zaakceptować. Może ktoś spojrzeć na to i wskazać mi w czym tkwi problem?

#include <cstdlib>
#include <iostream>
using namespace std;
int main()
{
    struct PKT
    {
       string nazwa; //nazwa pkt
       long long x;       //wsp. x
       long long y;       //wsp. y
       long long o;  //odleglosc od srodka ukladu
    };
    int t; //zmianna zawierająca ilość testów
    cin >> t;
    for(int x=0; x<t; x++) {
            int a; //zmienna zawierająca ilość punktów
            cin >> a;
            PKT p[a]; // tablica pkt
            for (int y=0; y<a; y++) {
                cin >> p[y].nazwa >> p[y].x >> p[y].y;
                p[y].o = (p[y].x*p[y].x) + (p[y].y*p[y].y);
            }
            if (a>1) {
                int zmiany;
                do {
                    zmiany = 0;
                    for (int y=0; y<a-1; y++) {
                        if (p[y].o > p[y+1].o) {
                            string stemp;
                            int temp, temp1, temp2;
                            stemp = p[y].nazwa;
                            temp = p[y].o;
                            temp1 = p[y].x;
                            temp2 = p[y].y;
                            p[y].nazwa = p[y+1].nazwa;
                            p[y].o = p[y+1].o;
                            p[y].x = p[y+1].x;
                            p[y].y = p[y+1].y;
                            p[y+1].nazwa = stemp;
                            p[y+1].o = temp;
                            p[y+1].x = temp1;
                            p[y+1].y = temp2;
                            zmiany++;
                        }
                    }
                } while (zmiany>1);
            }
            for (int y=0; y<a; y++) {
                cout << p[y].nazwa << ' ' << p[y].x << ' ' << p[y].y << endl;
            }
            cout << endl;
    }
    return 0;
}

Z góry dzięki za pomoc.

2 months later

w ktorym miejscu ma byc ta pusat linia??

#include <cstdlib>
#include <iostream>
#include <string.h>
#include <math.h>
using namespace std;
int main(int argc, char *argv[])
{
    string nazwa[10000];
    long long int x[10000],y[10000],t,ile;
    cin>>t;
    for(int i=0;i<t;i++){
            cin>>ile;
            for(int j=0;j<ile;j++){
                    cin>>nazwa[j]>>x[j]>>y[j];        
            }
            for(int j=0;j<ile*2;j++){
                    for(int z=0;z<ile-1;z++){
                            int x1 = (x[z]>0 ? x[z]: -x[z]);
                            int y1 = (y[z]>0 ? y[z]: -y[z]);
                            int x2 = (x[z+1]>0 ? x[z+1]: -x[z+1]);
                            int y2 = (y[z+1]>0 ? y[z+1]: -y[z+1]);
                            double l1 = sqrt(x1+y1);
                            double l2 = sqrt(x2+y2);
                            if(l1>l2){
                                            int tmp1=x[z],tmp2=y[z];
                                            x[z]=x[z+1];
                                            y[z]=y[z+1];
                                            x[z+1]=tmp1;
                                            y[z+1]=tmp2;
                                            string tmp=nazwa[z];
                                            nazwa[z]=nazwa[z+1];
                                            nazwa[z+1]=tmp;
                                            }
                    }
            }
            for(int xd=0;xd<ile;xd++)
                    cout<<nazwa[xd]<<" "<<x[xd]<<" "<<y[xd]<<endl;
                    cout<<endl;
    }
}
19 days later

#include <iostream>
#include <string>
using namespace std;
struct pkt{
public:
	string str;
	int x,y,o,i;
};
int main()
{
	int t,x,y,n;
	string str;
	cin >> t;
	while(t--)
	{
		cin >> n;
		pkt *p = new pkt [n];
		for(int i=0;i<n;i++)
		{
			cin >>p[i].str >> p[i].x >> p[i].y;
			p[i].o=(p[i].x*p[i].x+p[i].y*p[i].y);
		}
		int min=p[0].o, mini;
		for(int i=0;i<n;i++)
		{
			mini=i;
			for(int j=i;j<n;j++)
			{
				if(p[j].o<min)
				{
					min=p[j].o;
					mini=j;
				}
			}
			swap(p[i].str,p[mini].str);
			swap(p[i].x,p[mini].x);
			swap(p[i].y,p[mini].y);
			swap(p[i].o,p[mini].o);
		}
    	for(int i=0;i<n;i++)
	{
		cout << p[i].str << " " << p[i].x <<" "<< p[i].y <<" " << endl;
	}
	cout << endl;

}
//system("pause");
}

czemu WA? kto odpowie mi ;]?