A題
數組映射,讀入t, 則p[ t ]= i; for( i, 1, n ) cout<< p[i];
B題
十進位,三進位的轉換,+字串處理;
處理進位轉換的時候,要求反串,額,下面是代碼。
/*Feb 20, 2012 11:35:13 AMyimao B-Ternary Logic GNU C++Accepted 30ms 1400KB*/#include <cstdio>#include <cstring>#include <cmath>#include <iostream>#include <algorithm>using namespace std;#define MM(a,b) memset(a,b,sizeof(a));typedef long long lld;typedef unsigned long long u64;#define maxn 50void up_min(int &x,int y){if((x>y)||(x==-1))x=y;}int tran(int x,char *ch){ int t=0; while(x){ ch[t++]= x%3+'0'; x/= 3; } ch[t]= 0; return t;}lld trans2(char *ch, int n){ lld i, t=1, ret= 0; for(i=n-1;i>=0;--i){ ret+= t* (ch[i]-'0'); t*= 3; } return ret;}int main(){ //freopen("B.txt","r",stdin); int a,b,i,j; char ca[maxn], cb[maxn]; while(cin>>a>>b){ int na= tran( a, ca ); int nb= tran( b, cb ); if( na<nb ){ for(i=na;i<nb;++i) ca[i]='0'; ca[nb]= 0; na= nb; } else{ for(i=nb;i<na;++i) cb[i]= '0'; cb[na]= 0; nb= na; } for(i=0,j=na-1;i<j;++i,--j) swap( ca[i], ca[j] ); for(i=0,j=nb-1;i<j;++i,--j) swap( cb[i], cb[j] ); for(i=0;i<na;++i){ if( cb[i]>=ca[i] ){ ca[i]= cb[i]-ca[i]+'0'; } else{ ca[i]= cb[i]+3-ca[i]+'0'; } } lld ans= trans2( ca, na ); cout<< ans <<endl; }}
C題
給定n( n<= 100000 )個數位數列; 要求選擇一個數,用非本身的數代替,使得重新排序後,每個位置上的數最小,依次輸出這些最小的數。
易錯題。。。。。。。。。。。。。。
先sort,然後修改最後一個數字為1,再sort輸出,一開始我就這樣交,錯了。
原因是如果所有數都是1的話,最後一個數字必須改變為一個不是本身的數,那麼應該特判是否為1,如果是1,改為2後再sort;
D題
給定8個點,問是否可以得到一個正方形和一個長方形,如果可以輸出點編號組合。
代碼:
下面判斷是否是長方形的部分,m[]儲存的是4個點,我判斷這4個點是否可行的做法是枚舉他們的位置,按位置結合距離關係來判斷。
/*Feb 20, 2012 1:15:11 PM yimao D-Rectangle and Square GNU C++Accepted 30ms 1400KB*/#include <cstdio>#include <cstring>#include <cmath>#include <iostream>#include <algorithm>using namespace std;#define MM(a,b) memset(a,b,sizeof(a));typedef long long lld;typedef unsigned long long u64;#define maxnvoid up_min(int &x,int y){if((x>y)||(x==-1))x=y;}double x[10], y[10], dis[10][10];double Dis(int i,int j){ return ( x[i]-x[j] ) * ( x[i]-x[j] ) + ( y[i]-y[j] )*( y[i]-y[j] );}bool Judge_square(int i,int j,int k,int g){ if( dis[i][j]==dis[i][k] ){ if( dis[g][k]==dis[g][j] && dis[g][k]==dis[i][j] && dis[i][g]==dis[j][k] ) return 1; } if( dis[i][j]==dis[i][g] ){ if( dis[k][g]==dis[k][j] && dis[k][g]==dis[i][j] && dis[i][k]==dis[j][g] ) return 1; } if( dis[i][g]==dis[i][k] ){ if( dis[j][k]==dis[j][g] && dis[i][k]==dis[k][j] && dis[i][j]==dis[g][k] ) return 1; } return 0;}int m[5];bool Judge_rec(){ int i,j,k,g; for(i=1;i<=4;++i){ for(j=1;j<=4;++j){ if(m[i]!=m[j]){ for(k=1;k<=4;++k){ if(m[i]!=m[k]&&m[j]!=m[k]){ for(g=1;g<=4;++g){ if(m[g]!=m[i]&&m[g]!=m[j]&&m[g]!=m[k]){ if( dis[m[i]][m[j]]==dis[m[g]][m[k]] && dis[m[i]][m[g]]==dis[m[j]][m[k]] && dis[m[i]][m[k]]==dis[m[j]][m[g]] ) return 1; } } } } } } } return 0;}int main(){ //freopen("D.txt","r",stdin); int i,j,k,g; for(i=1;i<=8;++i){ scanf("%lf%lf",x+i, y+i); } for(i=1;i<8;++i) for(j=i+1;j<=8;++j){ dis[i][j]= Dis(i,j); dis[j][i]= dis[i][j]; } bool flag=0; for(i=1;i<6;++i){ for(j=i+1;j<7;++j){ for(k=j+1;k<8;++k){ for(g=k+1;g<=8;++g){ if( Judge_square(i,j,k,g) ){ int t=0; for(int cc=1;cc<=8;++cc) if( cc!=i && cc!=j && cc!=k && cc!=g ) m[++t]= cc; if( Judge_rec() ){ flag=1; goto loop; } } } } } } loop: if( !flag ) puts("NO"); else{ puts("YES"); printf("%d %d %d %d\n", i,j,k,g); printf("%d %d %d %d\n", m[1],m[2],m[3],m[4]); }}
E題
不會,
只有看懂解題報告後才知道這可以說是一個水題。
值得思考。
First, let's solve the problem when there are no spoiled cards. Let
a be the number of ones and
b be the number of zeroes. It is easy to see that if
a < b then the outcome is 00, because the first player can always remove ones until
they are over, which will happen before the end of the game regardless of the second player's moves. Similarly, if
a > b + 1 then the outcome is 11.If
a = b or
a = b + 1 then the outcome is either 01 or 10. That's because the first player will always remove ones, because otherwise the outcome will be 00 which is worse than any other outcome for him. Similarly, the second player will always
remove zeroes. One may notice that the first player can always remove the first card to the left with 1 written on it, because it won't make the outcome worse for him. Similarly, the second player can always remove the first card to the left with 0 written
on it. That means that the last card won't be removed by anyone. Thus is the last card is 1 then the outcome is 01, otherwise it is 10.We've learned how to solve the problem is there are no '?' signs. Now, suppose that the number of ones is
a, the number of zeroes is
band the number of question signs is
c. To check if the outcome 00 is possible, one can simply replace
all question signs with zeroes and use the previous result, i.e. check if
a < b + c. Similarly, the outcome 11 is possible is
a + c > b + 1.Let's show how to check if the outcome 01 is possible. If the last character of the string is 0, then the string is not possible. If the last character is ? then we can replace it with 1, i.e. decrease
c by 1 and increase
a by 1. Suppose we
want to replace
x question signs with one and
c - x question signs with zero. Then the following equality must hold:
x + a = b + c - x + (a + b + c) mod 2. Thus,
x = (b + c - a + (a + b + c) mod 2) / 2. If the resulting
value of x is non-negative and is not greater than c, then the outcome 01 is possible, otherwise it is not possible.We can check if the outcome 10 is possible in the similar way.