10778 - Why WA?
Posted: Sun Nov 28, 2004 8:32 pm
Why WA?
I read carefully the text of the problem:
1. first line contains two integers n and k.
2. All inputs/outputs will fit into a standard 32-bit signed integer.
3. extract the rational numbers in order of magnitude from the n-tuple
So the roots are rational and can be searched via full search.
If I have a0*x^n + a1*x^(n-1) +... + an, all rational roots p/q have
property: p divides an, q divides a0.
This is not clear:
Output all distinct solutions in lexicographical order, one in each line.
Should I output only distinct solutions? But sample output gives them.
Lexicographical order - what is it? It means 1 < 21 because 1 is less 2
lexicographicaly. But problem text clearly says that roots must be in non
descending order.
I tried a lot of tests, got right answers. Can you give me some tests?
Thanks.
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
int n,k,i,j,w;
int p[102];
int q1[102],q2[102];
int q1len, q2len, rt;
int root[102],temp;
double t;
double gorner(int degree,int n, int *c,double value)
{
if (!n) return c[degree];
else return value * gorner(degree,n-1,c,value) + c[degree-n];
}
int compare(const void *a, const void *b)
{
return *(int *)a - *(int *)b;
}
int factorize(int n,int *c)
{
int i,count = 0;
c[count++] = 1;
for(i=2;i<=(int)sqrt(n);i++)
{
if (n % i == 0)
{
c[count++] = i;
while(n % i == 0) n /= i;
}
}
if (n > 1) c[count++] = n;
return count;
}
int not_present(int v)
{
int i;
for(i=0;i<rt;i++)
if (root[i] == v) return 0;
return 1;
}
int main(void){
while(scanf("%d %d",&n,&k),n>0)
{
p[n] = k;
for(i=0;i<n;i++)
{
scanf("%d",&p[n-i-1]);
if (i %2 == 0) p[n-i-1] = -p[n-i-1];
}
rt = 0;
while(1)
{
t = gorner(n,n,p,0.0);
if (fabs(t) > 1e-8) break;
for(i=0;i<n;i++)
p[i] = p[i+1];
p[n--] = 0;
root[rt++] = 0;
}
w = rt;
q1len = factorize(abs(p[0]),q1);
q2len = factorize(k,q2);
for(i=0;i<q1len;i++)
for(j=0;j<q2len;j++)
{
t = gorner(n,n,p,1.0*q1[i]/q2[j]);
if (fabs(t) < 1e-8)
{
temp = k*q1[i]/q2[j];
if (not_present(temp)) root[rt++] = temp;
}
t = gorner(n,n,p,-1.0*q1[i]/q2[j]);
if (fabs(t) < 1e-8)
{
temp = -k*q1[i]/q2[j];
if (not_present(temp)) root[rt++] = temp;
}
}
temp = 1;
while(temp)
{
temp = 0;
for(i=0;i<n;i++)
p[i] = p[i+1]*(i+1);
p[n--] = 0;j=rt;
for(i=w;i<j;i++)
{
t = gorner(n,n,p,root[i]);
if (fabs(t) < 1e-8)
{
root[rt++] = root[i];
temp = 1;
}
}
}
if (rt > 0)
{
qsort(root,rt,sizeof(int),compare);
for(i=0;i<rt-1;i++)
printf("%d ",root[i]);
printf("%d\n",root[rt-1]);
} else printf("No solution.\n");
}
return 0;
}
I read carefully the text of the problem:
1. first line contains two integers n and k.
2. All inputs/outputs will fit into a standard 32-bit signed integer.
3. extract the rational numbers in order of magnitude from the n-tuple
So the roots are rational and can be searched via full search.
If I have a0*x^n + a1*x^(n-1) +... + an, all rational roots p/q have
property: p divides an, q divides a0.
This is not clear:
Output all distinct solutions in lexicographical order, one in each line.
Should I output only distinct solutions? But sample output gives them.
Lexicographical order - what is it? It means 1 < 21 because 1 is less 2
lexicographicaly. But problem text clearly says that roots must be in non
descending order.
I tried a lot of tests, got right answers. Can you give me some tests?
Thanks.
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
int n,k,i,j,w;
int p[102];
int q1[102],q2[102];
int q1len, q2len, rt;
int root[102],temp;
double t;
double gorner(int degree,int n, int *c,double value)
{
if (!n) return c[degree];
else return value * gorner(degree,n-1,c,value) + c[degree-n];
}
int compare(const void *a, const void *b)
{
return *(int *)a - *(int *)b;
}
int factorize(int n,int *c)
{
int i,count = 0;
c[count++] = 1;
for(i=2;i<=(int)sqrt(n);i++)
{
if (n % i == 0)
{
c[count++] = i;
while(n % i == 0) n /= i;
}
}
if (n > 1) c[count++] = n;
return count;
}
int not_present(int v)
{
int i;
for(i=0;i<rt;i++)
if (root[i] == v) return 0;
return 1;
}
int main(void){
while(scanf("%d %d",&n,&k),n>0)
{
p[n] = k;
for(i=0;i<n;i++)
{
scanf("%d",&p[n-i-1]);
if (i %2 == 0) p[n-i-1] = -p[n-i-1];
}
rt = 0;
while(1)
{
t = gorner(n,n,p,0.0);
if (fabs(t) > 1e-8) break;
for(i=0;i<n;i++)
p[i] = p[i+1];
p[n--] = 0;
root[rt++] = 0;
}
w = rt;
q1len = factorize(abs(p[0]),q1);
q2len = factorize(k,q2);
for(i=0;i<q1len;i++)
for(j=0;j<q2len;j++)
{
t = gorner(n,n,p,1.0*q1[i]/q2[j]);
if (fabs(t) < 1e-8)
{
temp = k*q1[i]/q2[j];
if (not_present(temp)) root[rt++] = temp;
}
t = gorner(n,n,p,-1.0*q1[i]/q2[j]);
if (fabs(t) < 1e-8)
{
temp = -k*q1[i]/q2[j];
if (not_present(temp)) root[rt++] = temp;
}
}
temp = 1;
while(temp)
{
temp = 0;
for(i=0;i<n;i++)
p[i] = p[i+1]*(i+1);
p[n--] = 0;j=rt;
for(i=w;i<j;i++)
{
t = gorner(n,n,p,root[i]);
if (fabs(t) < 1e-8)
{
root[rt++] = root[i];
temp = 1;
}
}
}
if (rt > 0)
{
qsort(root,rt,sizeof(int),compare);
for(i=0;i<rt-1;i++)
printf("%d ",root[i]);
printf("%d\n",root[rt-1]);
} else printf("No solution.\n");
}
return 0;
}