GCJ Qualification Round 2012
60pts(3703th)で通過。
A.
やるだけ。中括弧を使ってしまったのは反省しなければならない。
char decoding[] = {'y','h','e','s','o','c','v','x','d','u','i','g','l','b','k','r','z','t','n','w','j','p','f','m','a','q'}; int main(){ int T; string s; cin>>T; cin.ignore(); for(int X = 1; X <= T; X++){ string ans; getline(cin,s); for(int i = 0,l = s.size(); i < l; i++){ int c = s[i] - 'a'; if(0<=c && c<=26) c = decoding[c]; else c += 'a'; ans += c; } printf("Case #%d: ",X); cout<<ans<<endl; } return 0; }
B.
差が2未満で条件を満たすものと、差が2で条件を満たすものを数えて、貪欲に使う。
あと、得点が負にならないことに注意する。(sampleに無かったら、たぶん気づかなかったです。)
int T,N,S,p,t[100]; int main(){ scanf("%d",&T); for(int X = 1; X <= T; X++){ scanf("%d%d%d",&N,&S,&p); for(int i = 0; i < N; i++){ scanf("%d",t+i); } int A = 3*p-2; int B = 3*p-4; int ans = 0,surprising = 0; for(int i = 0; i < N; i++){ if(t[i]>=A) ans++; else if(t[i]>=B&&t[i]>=2) surprising++; } ans += min(surprising,S); printf("Case #%d: %d\n",X,ans); } return 0; }
C.
数字の一番右の桁の数字を一番左の桁に動かすことを繰り返して、できるようなペア(問題を読んでください)が、区間[A,B]にいくつあるか求める問題。
実際にぐるぐる回して、重複しないように数えれば解ける。
TLE(8分以内に提出できない)が怖かったから、inlineにしてみたけど、一瞬で解けたから大丈夫でした。
あと、一応long long にしましたが、最大ケースでもオーバーフローしてなかったと思います。
bool p[2000001]; inline int pow(int log){ int res = 1; for(int i = 0; i < log; i++){ res*=10; } return res; } inline int rot(int a,int log){ return a/10 + pow(log)*(a%10); } int main(){ int T; scanf("%d",&T); for(int X = 1; X <= T; X++){ memset(p,0,sizeof(p)); int A,B; long long ans = 0; scanf("%d%d",&A,&B); for(int i = max(A,10); i <= B; i++){ if(!p[i]){ long long res = 0; p[i] = true; int k = log10(i); int num = rot(i,k); while(i!=num){ if(A<=num && num<=B && k == (int)log10(num)){ p[num] = true; res++; } num = rot(num,k); } ans += res*(res+1)/2; } } printf("Case #%d: %lld\n",X,ans); } return 0; }
D.
光を鏡で反射させて、自分の所にいくつ戻ってくるかを求める問題。
Smallは全体が壁に覆われていて、その内側に鏡は無いらしいので、(ちゃんと実装できれば)Smallは解けた気がする。
とりあえず、DLしとけば良かった...(There will be no more than 2W+2H-4 '#' characters.の意味を分かってなかっただけです。)
Largeは途中に鏡があって、実装が大変そうです。