ACM/ICPC 国内予選 2011 提出コード

A問題

短く書こうとして関数名が省略形になってしまった

#include <iostream>
#include <algorithm>
#include <vector>
#include <cmath>
using namespace std;
#define REP(i,x) for(int i=0;i<(int)x;i++)
vector<bool> e_s(int n){
	vector<bool> res(n+1);
	res[0]=res[1]=false;
	res[2]=true;
	int i,j,m=sqrt(n)+1e-9;
	for(int i=3;i<=n;i+=2){
		if(i<=m){
			if(res[i]==false){
				for(j=i+i+i;j<=n;j+=i+i){
					res[j]=true;
				}
			}
		}
		res[i]=!res[i];
	}
	return res;
}

int main(){
	vector<bool> ip=e_s(1000000);
	for(int n;cin>>n,n;){
		int res=0;
		for(int i=n+1;i<=n*2;i++){
			res+=ip[i];
		}
		cout<<res<<endl;
	}
	return 0;
}

B問題

あまり簡潔ではない

#include <iostream>
#include <algorithm>
using namespace std;
#define REP(i,x) for(int i=0;i<(int)x;i++)
string replace(string exp,string src,string dst){
	int L=exp.size(),l=src.size();
	string res;
	REP(i,L){
		if(i<=L-l&&exp.substr(i,l)==src){
			res+=dst;
			i+=l-1;
		}else{
			res+=exp[i];
		}
	}
	return res;
}
int main(){
	for(;;){
		string in;
		getline(cin,in);
		if(in==".")break;
		string r;
		REP(i,in.size()){
			if(in[i]=='['||in[i]==']'||in[i]=='('||in[i]==')'){
				r+=in[i];
			}
		}
		while(1){
			int mL=r.size();
			//cout<<r<<endl;
			r=replace(r,"[]","");
			r=replace(r,"()","");

			if(mL==r.size())break;
		}
		//cout<<r<<endl;
		if(r==""){
			cout<<"yes"<<endl;
		}else{
			cout<<"no"<<endl;
		}
	}
	return 0;
}

C問題

targetをHにReplaceするとデバッグ前のコードになります.

#include <iostream>
#include <algorithm>
#include <vector>
#include <cstring>
#include <set>
#include <queue>
using namespace std;
#define REP(i,x) for(int i=0;i<(int)x;i++)
int MAP[10][10];
int cpy[10][10];
int W,H,c;
void show(){
	REP(i,H){
		REP(j,W){
			cout<<MAP[j][i]+1<<" ";
		}
		cout<<endl;
	}
	cout<<endl;
}
int ans=0;
typedef pair<int,int> P;
int dx[4]={0,-1,0,1},dy[4]={1,0,-1,0};
void BFS(int target){
	P p(0,0);
	queue<P> que;
	que.push(p);
	int sc=MAP[0][0];
	//cout<<sc<<endl;
	MAP[0][0]=-1;
	while(!que.empty()){
		P t=que.front();que.pop();
		//if(target==1)cout<<t.first<<","<<t.second<<":"<<sc<<endl;
		if(MAP[t.first][t.second]==target)continue;
		//if(target==1)cout<<"!"<<t.first<<","<<t.second<<endl;
		MAP[t.first][t.second]=target;
		REP(i,4){
			int nx=t.first+dx[i],ny=t.second+dy[i];
			if(nx>=0&&nx<W&&ny>=0&&ny<H){
				if(MAP[nx][ny]==sc)que.push(P(nx,ny));
			}
		}
	}
}
int BFSC(){
	P p(0,0);
	queue<P> que;
	que.push(p);
	int sc=MAP[0][0];
	int cnt=0;
	while(!que.empty()){
		P t=que.front();que.pop();
		if(MAP[t.first][t.second]==-1)continue;
		MAP[t.first][t.second]=-1;
		cnt++;
		REP(i,4){
			int nx=t.first+dx[i],ny=t.second+dy[i];
			if(nx>=0&&nx<W&&ny>=0&&ny<H)
				if(MAP[t.first+dx[i]][t.second+dy[i]]==sc)que.push(P(t.first+dx[i],t.second+dy[i]));
		}
	}
	return cnt;
}
int solve(int x){
	memcpy(cpy,MAP,sizeof(MAP));
	int tx=x;
	REP(i,4){
		tx/=6;
	}
	if(tx!=c)return 0;
	REP(i,5){
		BFS(x%6);
		x/=6;
	}
	if(MAP[0][0]==c){
		int t=BFSC();
		if(ans<t){
			//show();
		}
		ans=max(ans,t);

	}
	memcpy(MAP,cpy,sizeof(cpy));
}
int main(){
	for(;cin>>H>>W>>c;){
		if(W==0)break;
		REP(i,H){
			REP(j,W){
				cin>>MAP[j][i];
				MAP[j][i]-=1;
			}
		}


		c-=1;
		ans=0;
		REP(i,7776){
			solve(i);
		}
		cout<<ans<<endl;
	}
	return 0;
}

D問題

割と率直な実装

#include <iostream>
#include <algorithm>
#include <vector>
#include <cstring>
#include <set>
#include <queue>
#include <cmath>
#include <deque>
#define REP(i,x) for(int i=0;i<(int)x;i++)
using namespace std;
bool check(int x1,int y1,int r1,int x2,int y2,int r2){
	if((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)<(r1+r2)*(r1+r2)){
		return true;
	}
	return false;
}
struct Circle{
	int x,y,r,c;
	int can;
};
bool check(const Circle &a,const Circle &b){
	return check(a.x,a.y,a.r,b.x,b.y,b.r);
}

int n;
vector<Circle> datas;
int ans=0;
int preans=0;
set<int> ac;
#define precheck(a,b) (((a)|(b))==(a))
void dfs(int used){
	//cout<<used<<endl;
	if(ac.find(used)!=ac.end())return;
	ac.insert(used);
	ans=max(ans,preans);
	REP(i,n){
		if(((used>>i)&1)==0&&precheck(used,datas[i].can)){
			for(int j=i+1;j<n;j++){
				if(((used>>j)&1)==0){
					if(datas[i].c==datas[j].c&&precheck(used,datas[j].can)){
						preans+=2;
						dfs(used^(1<<j)^(1<<i));
						preans-=2;
					}
				}
			}
		}
	}
}
int main(){
	for(;cin>>n,n;){
		datas=vector<Circle>(n);
		REP(i,n){
			cin>>datas[i].x>>datas[i].y>>datas[i].r>>datas[i].c;
			datas[i].can=0;
		}
		for(int i=0;i<n;i++){
			for(int j=0;j<i;j++){
				if(check(datas[i],datas[j])){
					datas[i].can|=1<<j;
				}
			}
		}
		ac.clear();
		ans=0;
		preans=0;
		dfs(0);
		cout<<ans<<endl;
	}
	return 0;
}

E問題

始めてrepマクロを使いました.

#include <iostream>
#include <algorithm>
#include <vector>
#include <cstring>
#include <set>
#include <queue>
#include <cmath>
#include <deque>
#define REP(i,x) for(int i=0;i<(int)x;i++)
#define rep(i,s,e) for(int i=(s);i<(int)e;i++)
using namespace std;
//x1<=x<x2 , y1<=y<y2
int MAP[32][32];
typedef pair<int,int> P;
const P NA(-1,-1);
const P init(-2,-2);
P DP[33][33][33][33];
int dp[33][33][33][33];
int H,W,s,S;
int SUM(int x1,int y1,int x2,int y2){
	//if(dp[x1][y1][x2][y2]!=-1)return dp[x1][y1][x2][y2];
	int ans=0;
	rep(y,y1,y2){
		rep(x,x1,x2){
			ans+=MAP[x][y];
		}
	}
	return ans;
	//return dp[x1][y1][x2][y2]=ans;
}
P solve(int x1,int y1,int x2,int y2){
	if(S-SUM(x1,y1,x2,y2)>s)return NA;//解無し
	//cout<<"("<<x1<<","<<y1<<")"<<":"<<"("<<x2<<","<<y2<<")"<<endl;
	if(DP[x1][y1][x2][y2]!=init)return DP[x1][y1][x2][y2];
	P res=P(1,s-(S-SUM(x1,y1,x2,y2)));
	//x方向に分ける
	rep(x,x1+1,x2){
		P a,b;
		a=solve(x1,y1,x,y2);
		b=solve(x,y1,x2,y2);
		if(a==NA||b==NA)continue;
		P tmp;
		tmp=P(a.first+b.first,min(a.second,b.second));
		res=max(tmp,res);
	}

	//y方向に分ける
	rep(y,y1+1,y2){
		P a,b;
		a=solve(x1,y1,x2,y);
		b=solve(x1,y,x2,y2);
		if(a==NA||b==NA)continue;
		P tmp;
		tmp=P(a.first+b.first,min(a.second,b.second));
		res=max(tmp,res);
	}
	return DP[x1][y1][x2][y2]=res;
}
int main(){
	for(;cin>>H>>W>>s;){
		if(H==0)break;
		REP(i,H){
			REP(j,W){
				cin>>MAP[j][i];
			}
		}
		S=SUM(0,0,W,H);
		REP(i,33){
			REP(j,33){
				REP(k,33){
					REP(l,33){
						DP[i][j][k][l]=init;
					}
				}
			}
		}
		memset(dp,-1,sizeof(dp));
		P ans=solve(0,0,W,H);

		cout<<ans.first<<" "<<ans.second<<endl;
	}
	return 0;
}