昨天晚上做了一下,结果真的被虐爆了,考完之后毫无感觉,直接睡觉。。。
第一题超恶心,不仅要输出结果还要输出方案,打了半个小时草稿,
连计算方案的算法也没搞出来,只以为是搜索了,但因为后面两天没时间写了。。。
最后手算1~16输出,10分。。。
第二题:二进制的高精度Stein算法,一开始以为数字只会变小,就按照读入顺序存的
结果挂掉。。重写,因各种原因挂掉。。50
第三题,并查集,做过的,AC。
结果160,勉强第四。
如果第三题没有做过,就要100-,10+了。。。
PS:神奇地发现总分上升到第二。。。几个只会做水题的同学悲剧了。可以见得,多试对于选拔选手是有一定好处的。
好吧,总结一下。
首先是考试策略问题。
第一题的确是搜索,裸的ID-DFS就可以AC(写了不超过10分钟。。),完全不需要数学方法。。。
当然我看到了一个比我的程序10多倍的搜索程序,正在研究中。  

 裸的ID-DFS
裸的ID-DFS
 #include<cstdio>
#include<cstdio>
 #include<bitset>
#include<bitset>
 #include<cstring>
#include<cstring>
 #include<iostream>
#include<iostream>
 #include<fstream>
#include<fstream>
 #include<algorithm>
#include<algorithm>
 using namespace std;
    using namespace std;
 #define MM(a,i) memset(a,i,sizeof(a))
#define MM(a,i) memset(a,i,sizeof(a))
 #define FOR(i,a,b) for(int i=a;i<=b;i++)
#define FOR(i,a,b) for(int i=a;i<=b;i++)
 #define NFOR(i,a,b) for(i=a;i<=b;i++)
#define NFOR(i,a,b) for(i=a;i<=b;i++)
 #define DFOR(i,b,a) for(int i=b;i>=a;i--)
#define DFOR(i,b,a) for(int i=b;i>=a;i--)
 #define NDFOR(i,b,a) for(i=b;i>=a;i--)
#define NDFOR(i,b,a) for(i=b;i>=a;i--)
 #define PFOR(p,head,next) for(int p=head;p;p=next[p])
#define PFOR(p,head,next) for(int p=head;p;p=next[p])
 #define NPFOR(p,head,next) for(p=head;p;p=next[p])
#define NPFOR(p,head,next) for(p=head;p;p=next[p])
 int ans[16],depth,n,p;
    int ans[16],depth,n,p;
 void dfs(int i);
    void dfs(int i);
 ifstream fin("shulie.in");
    ifstream fin("shulie.in");
 ofstream fout("shulie.out");
    ofstream fout("shulie.out");

 int main()
    int main() {
{
 fin>>n;
        fin>>n;
 NFOR(depth,1,15)p=ans[1]=1,dfs(2);
        NFOR(depth,1,15)p=ans[1]=1,dfs(2);
 }
        }

 void dfs(int i)
    void dfs(int i) {
{

 if(ans[p]==n)
        if(ans[p]==n) {
{
 fout<<p<<"\n";
            fout<<p<<"\n";
 FOR(i,1,p-1)fout<<ans[i]<<" ";
            FOR(i,1,p-1)fout<<ans[i]<<" ";
 fout<<n,exit(0);
            fout<<n,exit(0);
 }
            }
 if(i>depth)return;
        if(i>depth)return;
 DFOR(k,p,1)//下一项是由最后一项和前p项中的任意一项构成的,易证其正确性
        DFOR(k,p,1)//下一项是由最后一项和前p项中的任意一项构成的,易证其正确性 
 p++,ans[p]=ans[p-1]+ans[k],dfs(i+1),p--;
            p++,ans[p]=ans[p-1]+ans[k],dfs(i+1),p--;
 }
        }


 快我10的代码(pas)
快我10的代码(pas)
 program shulie;
program shulie;
 var
 var
 a:array[1..20] of longint;
 a:array[1..20] of longint;
 i,j,k,n:longint;
 i,j,k,n:longint;

 procedure CloseFile;
procedure CloseFile;
 begin
 begin
 close(input); close(output); halt;
 close(input); close(output); halt;
 end;
 end;

 procedure dfs(step:longint);
procedure dfs(step:longint);
 var
 var
 i,j:longint;
 i,j:longint;
 begin
 begin
 for i:=step-1 downto 1 do
 for i:=step-1 downto 1 do
 for j:=step-1 downto i do
 for j:=step-1 downto i do
 begin
 begin
 a[step]:=a[i]+a[j];
 a[step]:=a[i]+a[j];
 if a[step]>n then continue;
 if a[step]>n then continue;
 if (a[step]<a[step-1]) or (a[step] shl (k-step)<n) then break;
 if (a[step]<a[step-1]) or (a[step] shl (k-step)<n) then break;
 if a[step]=n then
 if a[step]=n then
 begin
 begin
 writeln(k);
 writeln(k);
 for k:=1 to step-1 do
 for k:=1 to step-1 do
 write(a[k],' ');
 write(a[k],' ');
 writeln(a[step]);
 writeln(a[step]);
 CloseFile;
 CloseFile;
 end;
 end;
 if step<k then dfs(step+1);
 if step<k then dfs(step+1);
 end;
 end;
 end;
 end;

 begin
begin
 assign(input,'shulie.in'); reset(input);
 assign(input,'shulie.in'); reset(input);
 assign(output,'shulie.out'); rewrite(output);
 assign(output,'shulie.out'); rewrite(output);
 readln(n);
 readln(n);
 case n of
 case n of
 1:begin
 1:begin
 writeln(1); writeln(1); CloseFile;
 writeln(1); writeln(1); CloseFile;
 end;
 end;
 2:begin
 2:begin
 writeln(2); writeln(1,' ',2); CloseFile;
 writeln(2); writeln(1,' ',2); CloseFile;
 end;
 end;
 end;
 end;
 k:=2; a[1]:=1; a[2]:=2;
 k:=2; a[1]:=1; a[2]:=2;
 repeat
 repeat
 inc(k); dfs(3);
 inc(k); dfs(3);
 until false;
 until false;
 end.
end.第二题,一者是算法不全面(有可能就是错的),使代码过长。
            二者比较函数,写错了。。。
stein算法核心代码:
        int t=equal(a,b);
        if(t==2){gcd(b,a);return;}
        else if(t==0){copy(ans,b);return;}
        if(b[0]==1&&b[1]==1){copy(ans,b);return;}
        if((b[0]==1||b[0]==0)&&b[1]==0){copy(ans,a);return;}
        //
        if(!(b[1]&1)&&!(a[1]&1)){div2(a),div2(b),gcd(a,b),tim2(ans);return;}
        if((b[1]&1)&&(a[1]&1)){sub(a,b),gcd(a,b);return;}
         //这一类有两种方法gcd(a,b)=gcd((a+b)/2,(a-b)/2)  或 gcd(a,b)=gcd(a-b,b)实现起来差距巨大
        if(!(b[1]&1)&&(a[1]&1)){div2(b),gcd(a,b);return;}
        if((b[1]&1)&&!(a[1]&1)){div2(a),gcd(a,b);return;}

 完整代码
完整代码
 #include<cstdio>
#include<cstdio>
 #include<bitset>
#include<bitset>
 #include<cstring>
#include<cstring>
 #include<iostream>
#include<iostream>
 #include<fstream>
#include<fstream>
 #include<algorithm>
#include<algorithm>
 using namespace std;
 using namespace std;
 #define MM(a,i) memset(a,i,sizeof(a))
#define MM(a,i) memset(a,i,sizeof(a))
 #define FOR(i,a,b) for(int i=a;i<=b;i++)
#define FOR(i,a,b) for(int i=a;i<=b;i++)
 #define NFOR(i,a,b) for(i=a;i<=b;i++)
#define NFOR(i,a,b) for(i=a;i<=b;i++)
 #define DFOR(i,b,a) for(int i=b;i>=a;i--)
#define DFOR(i,b,a) for(int i=b;i>=a;i--)
 #define NDFOR(i,b,a) for(i=b;i>=a;i--)
#define NDFOR(i,b,a) for(i=b;i>=a;i--)
 #define PFOR(p,head,next) for(int p=head;p;p=next[p])
#define PFOR(p,head,next) for(int p=head;p;p=next[p])
 #define NPFOR(p,head,next) for(p=head;p;p=next[p])
#define NPFOR(p,head,next) for(p=head;p;p=next[p])
 const int INF=~0U>>2;
 const int INF=~0U>>2;
 const int maxn=1005;
 const int maxn=1005;
 typedef long long int64;
 typedef long long int64;
 //
//
 int L[maxn],R[maxn];
 int L[maxn],R[maxn];
 int ans[maxn];
 int ans[maxn];
 int S1[maxn],S2[maxn];
 int S1[maxn],S2[maxn];
 char c;
 char c;
 void gcd(int a[],int b[]);
 void gcd(int a[],int b[]);
 int equal(int a[],int b[]);
 int equal(int a[],int b[]);
 void sub(int a[],int b[]);//c=a-b
 void sub(int a[],int b[]);//c=a-b

 void copy(int a[],int b[])
 void copy(int a[],int b[]) {DFOR(i,a[0],0)a[i]=0;FOR(i,0,b[0])a[i]=b[i];}//a=b
{DFOR(i,a[0],0)a[i]=0;FOR(i,0,b[0])a[i]=b[i];}//a=b
 void div2(int a[]);//a/=2
 void div2(int a[]);//a/=2
 void tim2(int a[]);//a*=2;
 void tim2(int a[]);//a*=2;

 int main()
 int main() {
{
 freopen("bian.in","r",stdin);
 freopen("bian.in","r",stdin);
 freopen("bian.out","w",stdout);
 freopen("bian.out","w",stdout);
 int a[10],b[10];
 int a[10],b[10];
 MM(ans,0),MM(L,0),MM(R,0),MM(a,0),MM(b,0);
 MM(ans,0),MM(L,0),MM(R,0),MM(a,0),MM(b,0);

 for(;;)
 for(;;) {
{
 scanf("%c",&c);
 scanf("%c",&c);
 if(48<=c&&c<=49)L[0]++,L[L[0]]=c-48;
 if(48<=c&&c<=49)L[0]++,L[L[0]]=c-48;
 else break;
 else break;
 }
 } 
 FOR(i,1,L[0]/2)swap(L[i],L[L[0]-i+1]);
 FOR(i,1,L[0]/2)swap(L[i],L[L[0]-i+1]);

 for(;scanf("%c",&c)!=EOF;)
 for(;scanf("%c",&c)!=EOF;) {
{
 if(48<=c&&c<=49)R[0]++,R[R[0]]=c-48;
 if(48<=c&&c<=49)R[0]++,R[R[0]]=c-48;
 else break;
 else break; 
 }
 }
 FOR(i,1,R[0]/2)swap(R[i],R[R[0]-i+1]);
 FOR(i,1,R[0]/2)swap(R[i],R[R[0]-i+1]);
 gcd(L,R);
 gcd(L,R);
 DFOR(i,ans[0],1)printf("%d",ans[i]);
 DFOR(i,ans[0],1)printf("%d",ans[i]);
 }
 }

 void show(int a[])
 void show(int a[]) {DFOR(i,a[0],1)printf("%d",a[i]);}
{DFOR(i,a[0],1)printf("%d",a[i]);}

 void gcd(int a[],int b[])
 void gcd(int a[],int b[]) {//a>=b
{//a>=b
 int t=equal(a,b);
 int t=equal(a,b);

 if(t==2)
 if(t==2) {gcd(b,a);return;}
{gcd(b,a);return;}

 else if(t==0)
 else if(t==0) {copy(ans,b);return;}
{copy(ans,b);return;}

 if(b[0]==1&&b[1]==1)
 if(b[0]==1&&b[1]==1) {copy(ans,b);return;}
{copy(ans,b);return;}

 if((b[0]==1||b[0]==0)&&b[1]==0)
 if((b[0]==1||b[0]==0)&&b[1]==0) {copy(ans,a);return;}
{copy(ans,a);return;}
 //
 //

 if(!(b[1]&1)&&!(a[1]&1))
 if(!(b[1]&1)&&!(a[1]&1)) {div2(a),div2(b),gcd(a,b),tim2(ans);return;}
{div2(a),div2(b),gcd(a,b),tim2(ans);return;}

 if((b[1]&1)&&(a[1]&1))
 if((b[1]&1)&&(a[1]&1)) {sub(a,b),gcd(a,b);return;}
{sub(a,b),gcd(a,b);return;}

 if(!(b[1]&1)&&(a[1]&1))
 if(!(b[1]&1)&&(a[1]&1)) {div2(b),gcd(a,b);return;}
{div2(b),gcd(a,b);return;}

 if((b[1]&1)&&!(a[1]&1))
 if((b[1]&1)&&!(a[1]&1)) {div2(a),gcd(a,b);return;}
{div2(a),gcd(a,b);return;}
 //
 //
 }
 }

 void sub(int a[],int b[])
 void sub(int a[],int b[]) {
{

 FOR(i,1,b[0])
 FOR(i,1,b[0]) {
{
 a[i]-=b[i];
 a[i]-=b[i];
 while(a[i]<0)a[i]+=2,a[i+1]--;
 while(a[i]<0)a[i]+=2,a[i+1]--;
 }
 }
 FOR(i,1,a[0])while(a[i]<0)a[i]+=2,a[i+1]--;
 FOR(i,1,a[0])while(a[i]<0)a[i]+=2,a[i+1]--;
 while(a[a[0]]<=0)a[0]--;
 while(a[a[0]]<=0)a[0]--;
 }
 }

 void div2(int a[])
 void div2(int a[]) {
{
 FOR(i,1,a[0]-1)
 FOR(i,1,a[0]-1)
 a[i]=a[i+1];
 a[i]=a[i+1];
 a[0]--;
 a[0]--;
 }
 }

 void tim2(int a[])
 void tim2(int a[]) {
{
 DFOR(i,a[0]+1,2)
 DFOR(i,a[0]+1,2)
 a[i]=a[i-1];
 a[i]=a[i-1];
 a[1]=0;
 a[1]=0;
 a[0]++;
 a[0]++;
 }
 }

 int equal(int a[],int b[])
 int equal(int a[],int b[]) {//1:a>b 2:a<b 0:a==b
{//1:a>b 2:a<b 0:a==b
 if(a[0]>b[0])return 1;
 if(a[0]>b[0])return 1;
 else if(a[0]<b[0])return 2;
 else if(a[0]<b[0])return 2;
 DFOR(i,a[0],1)
 DFOR(i,a[0],1)
 if(a[i]>b[i])return 1;
 if(a[i]>b[i])return 1;
 else if(a[i]<b[i])return 2;
 else if(a[i]<b[i])return 2;
 return 0;
 return 0;
 }
 }

第三题,并查集,运用拆点法,把它拆成,本身的集合和相对的集合两个部分。然后很水的。。

 第二题不会fin的读入,所以用freopen,这个复制过来的。。。
第二题不会fin的读入,所以用freopen,这个复制过来的。。。
 #include<cstdio>
#include<cstdio>
 #include<cstring>
#include<cstring>
 #include<iostream>
#include<iostream>
 #include<fstream>
#include<fstream>
 #include<algorithm>
#include<algorithm>
 using namespace std;
 using namespace std;
 #define MM(a,i) memset(a,i,sizeof(a))
#define MM(a,i) memset(a,i,sizeof(a))
 #define FOR(i,a,b) for(int i=a;i<=b;i++)
#define FOR(i,a,b) for(int i=a;i<=b;i++)
 #define NFOR(i,a,b) for(i=a;i<=b;i++)
#define NFOR(i,a,b) for(i=a;i<=b;i++)
 #define DFOR(i,b,a) for(int i=b;i>=a;i--)
#define DFOR(i,b,a) for(int i=b;i>=a;i--)
 #define NDFOR(i,b,a) for(i=b;i>=a;i--)
#define NDFOR(i,b,a) for(i=b;i>=a;i--)
 #define PFOR(p,head,next) for(int p=head;p;p=next[p])
#define PFOR(p,head,next) for(int p=head;p;p=next[p])
 #define NPFOR(p,head,next) for(p=head;p;p=next[p])
#define NPFOR(p,head,next) for(p=head;p;p=next[p])
 const int INF=~0U>>2;
 const int INF=~0U>>2;
 const int maxn=50005;
 const int maxn=50005;
 typedef long long int64;
 typedef long long int64;
 int n,m;
 int n,m;
 int par[maxn*2],rank[maxn*2];
 int par[maxn*2],rank[maxn*2];
 int ans=0;
 int ans=0;
 int x,y,z;
 int x,y,z;

 int Getpar(int a)
 int Getpar(int a) {if(par[a]!=a)par[a]=Getpar(par[a]);return par[a];}
{if(par[a]!=a)par[a]=Getpar(par[a]);return par[a];}

 void Makeset(int a)
 void Makeset(int a) {par[a]=a;rank[a]=0;}
{par[a]=a;rank[a]=0;}

 void Union(int a,int b)
 void Union(int a,int b) {
{
 a=Getpar(a),b=Getpar(b);
 a=Getpar(a),b=Getpar(b);
 if(rank[a]>rank[b])par[b]=a;
 if(rank[a]>rank[b])par[b]=a;

 else
 else  {par[a]=b;
{par[a]=b;
 if (rank[a]==rank[b])rank[b]++;}
 if (rank[a]==rank[b])rank[b]++;}
 }
 }

 int main()
 int main() {
{
 freopen("str.in","r",stdin);
 freopen("str.in","r",stdin);
 freopen("str.out","w",stdout);
 freopen("str.out","w",stdout);
 scanf("%d %d",&n,&m);
 scanf("%d %d",&n,&m);
 FOR(i,0,maxn*2-1)Makeset(i);
 FOR(i,0,maxn*2-1)Makeset(i);

 FOR(i,1,m)
 FOR(i,1,m) {
{
 scanf("%d %d %d",&x,&y,&z);
 scanf("%d %d %d",&x,&y,&z);

 if(z==0)
 if(z==0) {
{

 if(Getpar(x-1)==Getpar(y+maxn))
 if(Getpar(x-1)==Getpar(y+maxn)) {ans++;continue;}
{ans++;continue;}
 Union(x-1,y);
 Union(x-1,y);
 Union(x-1+maxn,y+maxn);
 Union(x-1+maxn,y+maxn);
 }
 }

 else
 else {
{

 if(Getpar(x-1)==Getpar(y))
 if(Getpar(x-1)==Getpar(y)) {++ans;continue;}
{++ans;continue;}
 Union(x-1,y+maxn);
 Union(x-1,y+maxn);
 Union(x-1+maxn,y);
 Union(x-1+maxn,y);
 }
 }
 }
 }
 printf("%d\n",ans);
 printf("%d\n",ans);
 return 0;
 return 0;
 }
 }
