A没做
B地址 http://codeforces.com/problemset/problem/754/B
哎,一个可以说是普通的水题,却卡了一段时间WA数次由于考虑不周全和一些sb错误。
先是把题目中的'x'看做了'X',一口老血,后来懒得改上面(太多X了),就想着直接把x换成X,结果....在未修改完之后就进行判定导致WA,还少写了两个情况。
哎自己还是太粗心,代码能力有待提高啊= =
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<set> 6 #include<sstream> 7 using namespace std; 8 #define LOCAL 9 #define LL long long 10 #define ql(a) memset(a,0,sizeof(a)) 11 char e[15][15]; 12 bool ok(int x,int y) 13 {//if(x==2&&y==4)cout<<e[x][y-1]<<" "<<e[x][y-2]<<endl; 14 if(e[x][y-1]=='X'&&e[x][y-2]=='X') {return 1;} //每个三连有可能竖着,横着,主对角线,副对角线,这四种情况中待填充的位置又分为三个 15 if(e[x][y+1]=='X'&&e[x][y+2]=='X') {return 1;} //所以一共12种情况,当然嫌麻烦也可以用for找。 16 if(e[x-1][y]=='X'&&e[x-2][y]=='X') {return 1;} 17 if(e[x+1][y]=='X'&&e[x+2][y]=='X') {return 1;} 18 if(e[x][y-1]=='X'&&e[x][y+1]=='X') {return 1;} 19 if(e[x-1][y]=='X'&&e[x+1][y]=='X') {return 1;} 20 if(e[x+1][y-1]=='X'&&e[x+2][y-2]=='X') {return 1;} 21 if(e[x-1][y+1]=='X'&&e[x-2][y+2]=='X') {return 1;} 22 if(e[x+1][y-1]=='X'&&e[x-1][y+1]=='X') {return 1;} 23 if(e[x-1][y-1]=='X'&&e[x+1][y+1]=='X') {return 1;} 24 if(e[x+1][y+1]=='X'&&e[x+2][y+2]=='X') return 1; 25 if(e[x-1][y-1]=='X'&&e[x-2][y-2]=='X') return 1; 26 return 0; 27 } 28 int main() 29 { 30 31 int i,j,k; 32 for(i=2;i<=5;++i) 33 for(j=2;j<=5;++j) { 34 cin>>e[i][j]; 35 if(e[i][j]=='x') e[i][j]='X'; 36 } 37 bool ook=0; 38 for(i=2;i<=5;++i) 39 for(j=2;j<=5;++j){ 40 if(e[i][j]=='.'&&ok(i,j)) {ook=1;break;} 41 } 42 ook?puts("YES"):puts("NO"); 43 return 0; 44 }
C 不想说啥,多个字母有可能通过字符相连,妥善处理
D没开
E http://www.lydsy.com/JudgeOnline/problem.php?id=1083
贪心,n个点最少通过n-1条线连接,题目要使得最大权值的边的值最小化,
我们对所有边按照权值升序排列,每次利用并查集将边对应的两个点合并,当有效连接边达到n-1时此时当前边的权值就是答案。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<set> 6 using namespace std; 7 #define LOCAL 8 #define LL long long 9 #define ql(a) memset(a,0,sizeof(a)) 10 int f[333]; 11 int getf(int v){return f[v]==v?f[v]:f[v]=getf(f[v]);} 12 struct node 13 { 14 int u,v,w; 15 bool operator<(const node &c)const{ 16 return w<c.w; 17 } 18 }P[150000]; 19 int main() 20 { 21 int n,m,i,j,k; 22 while(cin>>n>>m){ 23 for(i=0;i<=n;++i) f[i]=i; 24 for(i=1;i<=m;++i){ 25 cin>>P[i].u>>P[i].v>>P[i].w; 26 } 27 sort(P+1,P+1+m); 28 int s=0; 29 for(i=1;i<=m;++i){ 30 int u=P[i].u,v=P[i].v; 31 int fu=getf(u),fv=getf(v); 32 if(fu!=fv){ 33 f[f[v]]=fu; 34 s++; 35 } 36 if(s==n-1){cout<<s<<" "<<P[i].w<<endl;break;} 37 } 38 } 39 return 0; 40 }
F.
有趣的一道状压DP,有趣当然是因为 47啦! 当年可是看了之后大爱这个光头大佬得吖! 可惜第二部换猪脚了= =
我们用dp[S]表示达到S状态(0表示未杀,1表示已杀)所花费的最小次数,初始化dp[0]=0 dp[other]=inf;
对于S,无论再杀死哪一个人,对应的状态都只会在S的后面,换句话说S更新别人的他自己肯定不会再被更新-。-
利用我为人人的方法更新后面状态的值, 对于S,遍历有0的位置更新将此为变为1后的状态,注意处理好hurt数组和向上取整。
如果用人人为我递推的话由于状态的不同写起来递推式很麻烦,不推荐。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<cmath> 5 using namespace std; 6 #define inf 0x3f3f3f3f 7 int dp[1<<15],N,K=0; 8 int hp[25],e[20][20]; 9 int hurt[25]; 10 void solve() 11 { 12 memset(dp,inf,sizeof(dp)); dp[0]=0; 13 for(int k=0;k<(1<<N);++k) 14 { 15 for(int i=0;i<N;++i) hurt[i]=1; 16 for(int i=0;i<N;++i) 17 { 18 if(k&(1<<i)) 19 for(int j=0;j<N;++j) hurt[j]=max(hurt[j],e[i][j]); 20 } 21 for(int i=0;i<N;++i) 22 { 23 if(!(k&(1<<i))){ 24 int tar=(k|(1<<i)); 25 dp[tar]=min(dp[tar],(int)(dp[k]+ceil(1.0*hp[i]/hurt[i]))); 26 } 27 } 28 } 29 printf("Case %d: %d ",++K,dp[(1<<N)-1]); 30 } 31 int main() 32 { 33 int t,i,j; 34 char c; 35 cin>>t; 36 while(t--){ 37 cin>>N; 38 for(i=0;i<N;++i) cin>>hp[i]; 39 for(i=0;i<N;++i) 40 for(j=0;j<N;++j) cin>>c,e[i][j]=c-'0'; 41 solve(); 42 } 43 return 0; 44 }
G.没写
H.sb了中间爆了long long一直没想到,该测几组大数据的
http://codeforces.com/problemset/problem/758/D
也是贪心(也可以dp?但贪心就很easy了)
要使得这个数最小,就要让最小位的数越大越好,注意这个数不能有前导零。
从后之前找数,尽可能接近n但不可>=n,每遇到一个临界点就 ans+=num*pow(n,p++) //p代表当前处理到的位
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<cmath> 5 #include<algorithm> 6 using namespace std; 7 #define inf 0x3f3f3f3f 8 #define LL long long 9 LL qpow(LL a,LL b) 10 { LL r=1; 11 while(b){ 12 if(b&1) r*=a; 13 b>>=1; 14 a*=a; 15 } 16 return r; 17 } 18 LL num(LL i,LL j,char a[]) 19 { 20 LL s=0; 21 for(LL k=i;k<=j;++k) s=s*10+(LL)(a[k]-'0'); 22 if(s<0) return 999999999; // 爆了long long 坑定大于n,返回一个极大值即可,表示这个数超n了 23 return s; 24 } 25 int main() 26 { 27 LL n,i,j,l,p=0; 28 char k[100]; 29 LL ans=0; 30 cin>>n>>k; 31 l=strlen(k); 32 for(i=l-1;i>=0;--i){bool ok=0; 33 for(j=0;j<i;++j) 34 { 35 if(k[j]=='0') continue; 36 LL t=num(j,i,k); 37 if(t<n) {ans+=t*qpow(n,p++);i=j;ok=1;break;} 38 } 39 if(!ok) ans+=(LL)(k[i]-'0')*qpow(n,p++); 40 41 } 42 cout<<ans<<endl; 43 return 0; 44 }