2010-05-23
Google Code Jam 2010 Round 1C
5/23 6pm〜
1Bで通ったので観戦モード(と言いつつ問題を解く)。
外出先から戻って18:25からのスタート。
時間内に3問とも解けた。終了後、practiceのデータを通したらC-large以外は全部通った。76点相当。実行時間+submitの手間を考慮しても141〜142位あたりで通過。
ていうか何でC-large通らなかったんだ?(後述)
A. Rope Intranet 18:32 (0:07)
- こういうの最近見た気がします
- あれだ。一昨日のSRM470 Div1 Medium
- バブルソートの回数でおk
#include <iostream>
#include <sstream>
#include <algorithm>
#include <string>
#include <vector>
#include <deque>
#include <stack>
#include <queue>
#include <list>
#include <map>
#include <set>
#include <cstdio>
#include <cmath>
#include <cctype>
using namespace std;
#define sz(a) int((a).size())
#define pb push_back
#define rep(var,n) for(int var=0,lim=(n);var<lim;var++)
#define REP(var,ar) for(int var=0,lim=(ar).size();var<lim;var++)
#define FOR(var,from,to) for(int var=(from),till=(to);var<=till;var++)
#define all(c) (c).begin(),(c).end()
#define rall(c) (c).rbegin(),(c).rend()
#define found(s,e) ((s).find(e)!=(s).end())
typedef pair<int,int> ii;
int main(){
int T; cin >> T;
rep(t,T){ // 15
int N; cin >> N;
vector<ii> wire(N);
rep(n,N){
int a, b; cin >> a >> b;
wire[n] = ii(a,b);
}
sort(all(wire));
int s=0;
rep(n,N){
rep(i,n) {
if(wire[n].second<wire[i].second)s++;
}
}
printf("Case #%d: %d\n", 1+t, s);
}
return 0;
}
B. Load Testing 18:48 (0:23)
皆さん題意がつかめずに苦労されていたようですが…
負荷テストを何度かやって、サーバがどこまでの負荷に耐えられるか知りたい。(求める負荷は厳密な数字ではなく)a≦x≦a*C みたいな範囲でわかればいい。あと何回負荷テストをしたら、要求する狭さで範囲が求まるか。
- 対数空間で二分探索する感じ。logの底がC、みたいな。
- たぶん答えは ceiling( log_2( log_C( P/L ) ) ) みたいな値
int main(){
int T; cin >> T;
rep(t,T){
int l,p,c; cin >> l >> p >> c; // 1<=L<P<=1e9, C:2..10
double x = log((double)p/l)/log((double)c);
int ans = max(0, (int)ceil(log(x)/log(2.0)));
printf("Case #%d: %d\n", 1+t, ans);
}
return 0;
}
- これで答えがあうよ
- でもチキンなので整数演算で書きました
// #include,#defineの内容はA,B,C共通なので省略
typedef pair<int,int> ii;
typedef long long ll;
int main(){
int T; cin >> T;
rep(t,T){
int l,p,c; cin >> l >> p >> c; // 1<=L<P<=1e9, C:2..10
ll L=l, P=p, C=c;
int ans;
if (P <= L*C) {
ans = 0;
} else {
ans=1;
for(ll j=L,m=C*C; j*m<P; m*=m)
ans++;
}
printf("Case #%d: %d\n", 1+t, ans);
}
return 0;
}
C. Making Chess Boards 19:40 (1:15)
与えられた白黒パターンの木版からチェス盤(というか市松模様)を切り出す問題。
大きい順、上から、左から、と明確に優先順位があるので一意に求まる。計算量だけの問題か。
- ある升目(行r,列c)から右にどれだけ市松模様が続いているか、をO(1)で分かるようにしておいて
- (r,c)を左上、(r+w-1,c+w-1)を右下とする幅w高さwの正方形を切り出したら市松模様になっているかの判定は、正方形の左端各行(r+i,c)からw以上市松模様が続いていることと、左端各行の色が交互に白黒白黒…となっていること
- 切り出した場所については、市松模様が続いていないのがわかる数字を設定しておけばよい(※ここでバグった)
// #include,#defineの内容はA,B,C共通なので省略
typedef pair<int,int> ii;
inline int unhex(char c){
if (c<='9') return c-'0';
else return c-'A'+10;
}
int main(){
int T; cin >> T;
rep(t,T){
int M,N; cin >> M >> N; // それぞれ4の倍数; 1-512/512
vector<vector<int> > bt(M,vector<int>(N,0));
vector<vector<int> > pt(M,vector<int>(N,0));
rep(m,M) {
string s; cin >> s;
rep(i,N/4){
int c=unhex(s[i]);
for(int j=0,mk=8;j<4;j++,mk>>=1){
//if (i*4+j >= N) cout << "err" << endl;
bt[m][i*4+j] = (c & mk)?1:0;
}
}
int cont=0, last=bt[m][N-1];
for(int i=N-1; i>=0; i--){
if (bt[m][i]==last) {
pt[m][i] = cont = 1;
} else {
pt[m][i] = ++cont;
}
last = bt[m][i];
}
}
int maxw=min(M,N), rest=M*N;
vector<int> ks(maxw+1,0);
for(int w=maxw; w>1; w--){
for(int sy=0; sy<=M-w; sy++) {
for(int sx=0; sx<=N-w; sx++) {
if (pt[sy][sx] < w) continue;
bool ok=true;
for(int r=1,po=bt[sy][sx]; r<w; r++){
int y=sy+r;
if (pt[y][sx] < w || bt[y][sx]==po) { ok=false; break; }
po = 1 - po;
}
if (ok) { // take it
ks[w]++; rest -= w*w;
rep(r,w) {
int y=sy+r;
rep(c,w){
pt[y][sx+c] = 0;
}
if (sx==0) continue;
int b=pt[y][sx-1];
for (int x=sx-1; x>=0; x--){
if (pt[y][x]==1) break; ///OOPS
pt[y][x]-=b-1; //printf(" (%d,%d)-%d=%d¥n", x,y,b, pt[y][x]);
}
}
}
}
}
}
ks[1] = rest;
vector<ii> res;
for(int w=1; w<=maxw; w++) {
if (ks[w] > 0) res.pb(ii(w,ks[w]));
}
reverse(all(res));
int K=sz(res);
printf("Case #%d: %d¥n", t+1, K);
rep(k,K) {
printf("%d %d¥n", res[k].first, res[k].second);
}
}
return 0;
}
C-large (practice) を通しても1秒で終わる。しかしincorrectだ…オーバーフローは無いはずだし何でだろうと思ってソースを見返したら
if (pt[y][x]==1) break;
がおかしい。既にチェス盤を切り出した所であれば0になっているはずだしそれならbreakしてほしい。
if (pt[y][x]<=1) break;
が正しい。これでC-largeも通った。(C-smallが通ったのは偶然だろう)
というわけで皆さんお疲れ様でした。次はRound 2でお会いしましょう。
コメント
トラックバック - https://topcoder-g-hatena-ne-jp.jag-icpc.org/n4_t/20100523