谈点今天的感想,五个小时,在一道题上卡死了,说明简单题不熟,找了半天没找出错来,太异想天开,以后遇到这种情况,可以写一写试试,而不是抱怨,不多说了,还得加强啊,继续努力。
upc2502:
比赛结束,听人家一说,感觉自己做麻烦了。
#include<iostream>
#include<string>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
struct A
{
int i,time;
};
bool com(A x,A y)
{
return x.time<y.time;
}
int main()
{
// freopen("in.txt","r",stdin);
int n;
char a[1000];
int loop=1;
char cach[30];
A b[30],c[30];
while(cin>>n,n)
{
getchar();
cin>>a;
getchar();
int t=1,tim=1;
cout<<"Simulation "<<loop++<<endl;
for(int j=1; j<=n; j++)
b[j].i=b[j].time=c[j].i=c[j].time=0;
memset(cach,'\0',sizeof(cach));
for(int i=0; i<strlen(a); i++)
{
if(a[i]=='!')
{
int l=n;
if(t<=n)
l=t-1;
memset(c,0,sizeof(c));
for(int j=1; j<=l; j++)
c[j]=b[j];
stable_sort(c+1,c+l+1,com);
for(int j=1; j<=l; j++)
cout<<cach[c[j].i];
cout<<endl;
}
else
{
int l=n;
if(t<=n)
l=t-1;
int flag=0;
for(int j=1; j<=l; j++)
if(cach[j]==a[i])
{
b[j].time=tim;
//b[j].i=j;
flag=1;
break;
}
if(flag)
{
tim++;
continue;
}
if(t<=n)
{
cach[t]=a[i];
b[t].i=t;
b[t].time=tim;
}
else
{
int min1=100000,p;
for(int j=1; j<=n; j++)
if(b[j].time<min1)
{
min1=b[j].time;
p=j;
}
cach[p]=a[i];
b[p].time=tim;
}
t++;
tim++;
}
}
}
return 0;
}
upc2497:
刚开始没思路,当你看完百度百科关于勾股数的介绍,就知道怎么做了。
百度百科:
所谓勾股数,一般是指能够构成
直角三角形三条边的三个正整数(a,b,c)。
即a2+b2=c2,a,b,c∈N
关于这样的数组,比较常用也比较实用的套路有以下两种:
第一套路
当a为大于1的
奇数2n+1时,b=2n^2+2n, c=2n^2+2n+1。
n=1时(a,b,c)=(3,4,5)
n=2时(a,b,c)=(5,12,13)
n=3时(a,b,c)=(7,24,25)
... ...
第二套路
2、当a为大于4的偶数2n时,b=n^2-1, c=n^2+1
也就是把a的一半的平方分别减1和加1,例如:
n=3时(a,b,c)=(6,8,10)
n=4时(a,b,c)=(8,15,17)
n=5时(a,b,c)=(10,24,26)
n=6时(a,b,c)=(12,35,37)
... ...
这是第二经典的套路,当n为奇数时由于(a,b,c)是三个偶数,所以该勾股数组必然不是
互质的;而n为偶数时由于b、c是两个连续奇数必然互质,所以该勾股数组互质。
所以如果你只想得到
互质的数组,这条可以改成,对于a=4n (n>=2), b=4n2-1, c=4n2+1,例如:
n=2时(a,b,c)=(8,15,17)
n=3时(a,b,c)=(12,35,37)
n=4时(a,b,c)=(16,63,65)
... ...
编辑本段公式证明
证明
a=2mn
b=m^2-n^2
c=m^2+n^2
证:
假设a^2+b^2=c^2,这里研究(a,b)=1的情况(如果不等于1则(a,b)|c,两边除以(a,b)即可)
等式化为4k^2 = (c+b)(c-b)
显然b,c同奇偶(否则右边等于
奇数矛盾)
作代换:M=(c+b)/2, N=(c-b)/2,显然M,N为
正整数
往证:(M,N)=1
如果存在质数p,使得p|M,p|N, 那么p|M+N(=c), p|M-N(=b), 从而p|c, p|b, 从而p|a,这与(a,b)=1矛盾
所以(M,N)=1得证。
如果对于某个pi,M的pi因子个数为奇数个,那N对应的pi因子必为奇数个(否则加起来不为偶数),从而pi|M, pi|N,(M,N)=pi>1与刚才的证明矛盾 所以对于所有
质因子,pi^2|M, pi^2|N,即M,N都是
平方数。
设M = m^2, N = n^2
从而有c+b = 2m^2, c-b = 2n^2,解得c=m^2+n^2, b=m^2-n^2, 从而a=2mn
局限
关于勾股数的公式还是有局限的。勾股数公式可以得到所有的基本勾股数,但是不可能得到所有的派生勾股数。比如3,4,5;6,8,10;9,12,15...,就不能全部有公式计算出来。
编辑本段完全公式
公式
a=m,b=(m^2 / k - k) / 2,c=(m^2 / k + k) / 2 ①
其中m ≥3
⒈ 当m确定为任意一个 ≥3的奇数时,k={1,m^2的所有小于m的因子}
⒉ 当m确定为任意一个 ≥4的
偶数时,k={m^2 / 2的所有小于m的偶数因子}
基本勾股数与派生勾股数可以由完全一并求出。例如,当m确定为
偶数432时,因为k={432^2 / 2的所有小于432的偶数因子}= {2,4,6,8,12,16,18,24,32,36,48,54,64,72,96,108,128,144,162,192,216,288,324,384},将m=432及24组不同k值分别代入b=(m^2 / k - k) / 2,c=(m^2 / k + k) / 2;即得直角边a=432时,具有24组不同的另一直角边b和斜边c,基本勾股数与派生勾股数一并求出。而勾股数的
组数也有公式能直接得到。
组数N
算术基本定理:一个大于1的正整数n,如果它的标准
分解式为n=p1^m1×p2^m2×……×pr^mr,那么它的正
因数个数为N=(m1+1)×(m2+1)×……×(mr+1);依据定理,易得以下结论
当a给定时,不同勾股数组a,b,c的
组数N等于①式中k的可取值个数
⒈ 取奇数a=p1^m1×p2^m2×……×pr^mr,其中k={1,a^2的所有小于a的因子},则k的可取值个数:
N=[(2m1+1)×(2m2+1)×……×(2mr+1)-1]/2
⒉ 取
偶数a=2^m0×p1^m1×p2^m2×……×pr^mr,其中k={a^2 / 2的所有小于a的偶数因子},则k的可取值个数:
N=[(2m0-1)×(2m1+1)×(2m2+1)×……×(2mr+1)-1]/2
其中,p1,p2,……,pr为互不相同的奇素数,m0,m1,……,mr为幂指数。
#include<iostream>
using namespace std;
int main()
{
long long m;
while(cin>>m,m)
{
long long ans=0;
if(m==2)
cout<<0<<endl;
else if(m==3)
cout<<1<<endl;
else
{
if(m%2)
{
long long k=m*m;
for(long long i=m; i>=1; i--)
{
if(k%i==0)
{
if((k/i-i)/2>m)
ans++;
}
}
}
else
{
long long k=m*m/2;
for(long long i=m;i>=1;i--)
if(i%2==0&&k%i==0)
if((k*2/i-i)/2>m)
ans++;
}
cout<<ans<<endl;
}
}
return 0;
}