哈理工多校算法赛一
题目链接:https://www.nowcoder.com/acm/contest/67#question
来源:牛客网
A 吃鸡
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <bits/stdc++.h> using namespace std; int main() { int n,m; while(~scanf("%d%d",&n,&m)) { int arr[n][1005]; for(int i=0;i<n;i++) { scanf("%d%d",&arr[i][0],&arr[i][1]); for(int j=2;j<=1+arr[i][1];j++) scanf("%d",&arr[i][j]); } int p,u=m; double brr[1005]={0},b,sum=0; while(m--) { scanf("%d",&p); scanf("%lf",&b); if(brr[p]==0) brr[p]=b; else brr[p]=max(b,brr[p]); } for(int i=0;i<n;i++) { double jc=1; for(int j=2;j<=1+arr[i][1];j++) jc+=brr[arr[i][j]]; sum=max(sum,arr[i][0]*jc); } printf("%.4f\n",sum); } return 0; }
利用桶排序的思想存放配件加成值更方便
B 游戏王
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <bits/stdc++.h> using namespace std; int value,sum; int arr[1005][3]; stack<int> LS; void _one() { LS.pop(); value+=LS.top(); } void _two() { LS.pop(); value+=sum*LS.top(); } void _init() { while(!LS.empty()) LS.pop(); } int main() { int n; while(~scanf("%d",&n)) { value=0; sum=1; ///value记录伤害总值 sum记录栈内操作的个数 int s,t; for(int i=0;i<n;i++) { scanf("%d%d",&arr[i][0],&arr[i][1]); if(arr[i][1]==1||arr[i][1]==2) scanf("%d",&arr[i][2]); } ///生成图 0~n-1 不包括n _init(); //初始化栈 if(arr[0][1]==1||arr[0][1]==2) LS.push(arr[0][2]); /* A:若为1 2操作 则将对应的x伤害值压入栈*/ LS.push(arr[0][1]); for(int i=1;i<=n;i++) /// 此时范围之所以包括n { /// 是因为最后一个操作(n-1)压入栈后 /// 还需要进行连锁伤害操作 if(arr[i][0]>=arr[i-1][0]&&i<n)//此处排除n的情况 因为不存在 { if(arr[i][1]==1||arr[i][1]==2) LS.push(arr[i][2]);// 同A LS.push(arr[i][1]); sum++; } ///若发动速度符合 后者大于前者 的条件 则持续压入栈内 if(arr[i][0]<arr[i-1][0]||i==n) ///一旦不符合条件 则开始连锁伤害 { while(!LS.empty()) { if(LS.top()==1) _one(); else if(LS.top()==2) _two(); else if(LS.top()==3) _init(); else if(LS.top()==4) { LS.pop(); sum--; if(!LS.empty()&&(LS.top()==1||LS.top()==2)) LS.pop(); } /* B:注意这里!一定要判断LS栈是否为空 再决定是否pop 因为之前出栈过 此时栈内可能为空 */ if(!LS.empty()) { LS.pop(); /// 同B sum--; } } ///此时操作完一套连锁 继续后面操作 if(arr[i][1]==1||arr[i][1]==2) LS.push(arr[i][2]); // 同A LS.push(arr[i][1]); sum=1; } } printf("%d\n",value); } return 0; }
百度发现某位大佬的解法比我的更精简
拜上链接 http://blog.csdn.net/deaidai/article/details/79124656
C 六子冲
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <bits/stdc++.h> using namespace std; int a[5][5],x,y; int pd(int g) { if(g<=6&&g>=1) return 1; else return 0; } void up_dow() { if(x==1) { if(pd(a[x+1][y])==pd(a[x][y])&&pd(a[x+2][y])!=pd(a[x][y]) &&!a[x+3][y]&&a[x+1][y]&&a[x+2][y]) a[x+2][y]=0; } else if(x==2) { if(pd(a[x-1][y])==pd(a[x][y])&&pd(a[x+1][y])!=pd(a[x][y]) &&!a[x+2][y]&&a[x-1][y]&&a[x+1][y]) a[x+1][y]=0; else if(pd(a[x-1][y])!=pd(a[x][y])&&a[x+1][y]&&a[x-1][y] &&pd(a[x+1][y])==pd(a[x][y])&&!a[x+2][y]) a[x-1][y]=0; else if(pd(a[x+2][y])!=pd(a[x][y])&&a[x+2][y]&&a[x+1][y] &&pd(a[x+1][y])==pd(a[x][y])&&!a[x-1][y]) a[x+2][y]=0; } else if(x==3) { if(pd(a[x+1][y])==pd(a[x][y])&&a[x+1][y]&&a[x-1][y] &&pd(a[x-1][y])!=pd(a[x][y])&&!a[x-2][y]) a[x-1][y]=0; else if(pd(a[x+1][y])!=pd(a[x][y])&&a[x+1][y]&&a[x-1][y] &&pd(a[x-1][y])==pd(a[x][y])&&!a[x-2][y]) a[x+1][y]=0; else if(pd(a[x-2][y])!=pd(a[x][y])&&a[x-1][y]&&a[x-2][y] &&pd(a[x-1][y])==pd(a[x][y])&&!a[x+1][y]) a[x-2][y]=0; } else { if(pd(a[x-1][y])==pd(a[x][y])&&a[x-1][y]&&a[x-2][y] &&pd(a[x-2][y]!=pd(a[x][y])&&!a[x-3][y])) a[x-2][y]=0; } return; } void le_rig() { if(y==1) { if(pd(a[x][y+1])==pd(a[x][y])&&a[x][y+2]&&a[x][y+1] &&pd(a[x][y+2])!=pd(a[x][y])&&!a[x][y+3]) a[x][y+2]=0; } else if(y==2) { if(pd(a[x][y-1])==pd(a[x][y])&&a[x][y+1]&&a[x][y-1] &&pd(a[x][y+1])!=pd(a[x][y])&&!a[x][y+2]) a[x][y+1]=0; else if(pd(a[x][y-1])!=pd(a[x][y])&&a[x][y-1]&&a[x][y+1] &&pd(a[x][y+1])==pd(a[x][y])&&!a[x][y+2]) a[x][y-1]=0; else if(pd(a[x][y+2])!=pd(a[x][y])&&a[x][y+2]&&a[x][y+1] &&pd(a[x][y+1])==pd(a[x][y])&&!a[x][y-1]) a[x][y+2]=0; } else if(y==3) { if(pd(a[x][y-1])==pd(a[x][y])&&a[x][y-1]&&a[x][y+1] &&pd(a[x][y+1])!=pd(a[x][y])&&!a[x][y-2]) a[x][y+1]=0; else if(pd(a[x][y-1])==pd(a[x][y])&&a[x][y-2]&&a[x][y-1] &&pd(a[x][y-2])!=pd(a[x][y])&&!a[x][y+1]) a[x][y-2]=0; else if(pd(a[x][y-1])!=pd(a[x][y])&&a[x][y+1]&&a[x][y-1] &&pd(a[x][y+1])==pd(a[x][y])&&!a[x][y-2]) a[x][y-1]=0; } else { if(pd(a[x][y-1])==pd(a[x][y])&&a[x][y-1]&&a[x][y-2] &&pd(a[x][y-2])!=pd(a[x][y])&&!a[x][y-3]) a[x][y-2]=0; } return; } int main() { int n,i=1; while(~scanf("%d",&n)) { a[1][1]=11;a[1][2]=10;a[1][3]=9;a[1][4]=8; a[2][1]=12;a[2][2]= 0;a[2][3]=0;a[2][4]=7; a[3][1]= 1;a[3][2]= 0;a[3][3]=0;a[3][4]=6; a[4][1]= 2;a[4][2]= 3;a[4][3]=4;a[4][4]=5; while(n--) { int q,p; scanf("%d%d",&q,&p); for(x=1;x<=4;x++) { for(y=1;y<=4;y++) if(a[x][y]==q) break; if(y<=4) break; } switch(p) { case 1: if(x>1) { a[x][y]=a[x-1][y]; a[x-1][y]=q; x--; } break; case 2: if(x<4) { a[x][y]=a[x+1][y]; a[x+1][y]=q; x++; } break; case 3: if(y>1) { a[x][y]=a[x][y-1]; a[x][y-1]=q; y--; } break; case 4: if(y<4) { a[x][y]=a[x][y+1] ;a[x][y+1]=q; y++; } break; } up_dow(); le_rig(); } printf("#Case %d:\n",i++); for(int k=1;k<=4;k++) { for(int j=1;j<=4;j++) printf("%3d",a[k][j]); printf("\n"); } } return 0; }
不清楚差了些什么 只过了%20的样例
题解http://blog.csdn.net/jaihk662/article/details/79121335
D N阶汉诺塔
网上某位大佬的思路 厉害 奈何看不懂代码
https://www.cnblogs.com/widsom/p/8331657.html
自己按思路写了一个 递归得出操作步骤存入数组 再根据数组内的操作步骤执行到第k步
但没注意内存限制 根本开不下3^40的数组 卒
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <bits/stdc++.h> using namespace std; stack <int> A,B,C; int a[1000000],k,x; void sel(int i) { switch(i) { case 1: B.push(A.top());A.pop();break; case 2: C.push(B.top());B.pop();break; case 3: B.push(C.top());C.pop();break; case 4: A.push(B.top());B.pop();break; } } void ope(int j,int o) { if(j>k) return; int m=0; for(int i=1;i<=k/pow(3,o-1);i++) { if(i%3) { m++; a[j*i]= m%4 ? m%4 : 4 ; } else if(i==3) ope(j*i,o+1); } } void init() { while(!A.empty()) A.pop(); while(!B.empty()) B.pop(); while(!C.empty()) C.pop(); } void print() { stack <int> a,b,c; while(!A.empty()) { a.push(A.top()); A.pop(); } while(!B.empty()) { b.push(B.top()); B.pop(); } while(!C.empty()) { c.push(C.top()); C.pop(); } int fa=0,fb=0,fc=0; while(!a.empty()) { printf("%d ",a.top()); a.pop(); fa=1; } if(!fa) printf("0"); printf("\n"); while(!b.empty()) { printf("%d ",b.top()); b.pop(); fb=1; } if(!fb) printf("0"); printf("\n"); while(!c.empty()) { printf("%d ",c.top()); c.pop(); fc=1; } if(!fc) printf("0"); printf("\n"); } int main() { int n; while(~scanf("%d%d",&n,&k)) { init(); for(int i=n;i>=1;i--) A.push(i); x=1; ope(1,1); for(int i=1;i<=k;i++) sel(a[i]); print(); } return 0; }
另一份C/C++题解 http://blog.csdn.net/Jaihk662/article/details/79121367
补:参透了大佬的代码 自己用栈做了一遍 但是不知道为什么还是过不了
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<bits/stdc++.h> using namespace std; int main() { int n,k; while(~scanf("%d%d",&n,&k)) { stack <int> A,B,C; while(!A.empty()) A.pop(); while(!B.empty()) B.pop(); while(!C.empty()) C.pop(); int m=1; for(int i=1;i<=n;i++) { int t=(k/m)%6; if(t>2) t=5-t; if(t==0) A.push(i); else if(t==1) B.push(i); else C.push(i); m*=3; } int fa,fb,fc; fa=fb=fc=0; while(!A.empty()) { if(A.size()==1) printf("%d\n",A.top()); else printf("%d ",A.top()); A.pop(); fa=1; } if(fa==0) printf("0\n"); while(!B.empty()) { if(B.size()==1) printf("%d\n",B.top()); else printf("%d ",B.top()); B.pop(); fb=1; } if(fb==0) printf("0\n"); while(!C.empty()) { if(C.size()==1) printf("%d\n",C.top()); else printf("%d ",C.top()); C.pop(); fc=1; } if(fc==0) printf("0\n"); } return 0; }
E 恋与程序员
(SYS的代码)
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<bits/stdc++.h> using namespace std; int use[101],w[101][101],cost[101],n,m,k,t,ans=INT_MAX; ///use[]标记卡片是否买了,cost[]卡片的价格;w[](u,v矩阵),ans 最小花费; int book[101]; void dfs(int o,int sum) { if(o==t) ///找到了 这里的t是c即顶点数 { ans=min(ans,sum);/*if (ans>sum) min=dis; return;*/ return; }///令ans取最小值 for(int i=1;i<=n;i++)///遍历从1到C依次尝试 { if(w[o][i]!=0) { if(use[w[o][i]]==0) { use[w[o][i]]=1; dfs(i,sum+cost[w[o][i]]);///当前花费 use[w[o][i]]=0;///取消标记 } else dfs(i,sum);///直接遍历下一个点。 } /*if(w[o][i]!=0&&book[i]==0) ///有通道 { book[i]=1; dfs(i,sum+cost[w[o][i]]);///当前花费; book[i]=0;///取消标记 } else dfs(i,sum);*/ } } int main () { while(~scanf("%d%d%d%d",&n,&m,&k,&t)) { /*for(i=1;i<=n;i++) for(j=1;j<=n;j++) if(i==j) w[i][j]=0; else w[i][j]=999999999;*/ memset(w,0,sizeof (w));///初始化赋值为零 ans=INT_MAX;///c++中通过设置INT_MAX便于比较最大值或者最小值! for(int i=1,u,v,z;i<=m;i++) { scanf("%d%d%d",&u,&v,&z); w[u][v]=z;///单向图! } for(int i=1,x,y;i<=k;i++) { scanf("%d%d",&x,&y); cost[x]=y;///x卡片的价格,通过数组便于找到下标!! } ///book[1]=1; dfs(1,0);///表示当前城市的编号,0表示已走过的路程。 printf("%d\n",ans); } } /* 6 7 5 6 2 3 2 4 3 3 1 2 1 1 5 4 4 6 5 1 4 2 5 6 3 1 100 3 422 2 210 5 107 4 38 */
自己做了一遍
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <bits/stdc++.h> using namespace std; int n,m,k,c,ans; int a[105][105],price[1005],used[1005]; void DFS(int i,int sum) { if(i==c) { ans=min(sum,ans); return; } for(int j=2;j<=n;j++) { if(a[i][j]) if(!used[a[i][j]]) { used[a[i][j]]=1; DFS(j,sum+price[a[i][j]]); used[a[i][j]]=0; } else DFS(j,sum); } } int main() { while(~scanf("%d%d%d%d",&n,&m,&k,&c)) { ans=1e9; memset(a,0,sizeof(a)); memset(price,0,sizeof(price)); memset(used,0,sizeof(used)); while(m--) { int u,v,e; scanf("%d%d%d",&u,&v,&e); a[u][v]=e; } while(k--) { int a,b; scanf("%d%d",&a,&b); price[a]=b; } DFS(1,0); printf("%d\n",ans); } return 0; }
F 跑毒
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <bits/stdc++.h> int main() { int t; scanf("%d",&t); while(t--) { int a,b,c; scanf("%d%d%d",&a,&b,&c); int dis=0,blood=100; while(c>0&&dis<b) { while(blood>6*a) { blood-=a; dis++; } dis--; c--; blood=80; } if((b-dis-1)*a<80) printf("YES\n"); else printf("NO\n"); } return 0; }
G 圆圈
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <bits/stdc++.h> using namespace std; char a[7000][7000]; int power[10]; void change(int n,int i,int j) { if(n==0) { a[i][j]='O'; return; } else { int m=power[n-1]; change(n-1,i,j+m); change(n-1,i+m,j);change(n-1,i+m,j+2*m); change(n-1,i+2*m,j+m); } } int main() { int t; scanf("%d",&t); power[0]=1; for(int i=1;i<=8;i++) power[i]=power[i-1]*3; while(t--) { int n; scanf("%d",&n); for(int i=0;i<power[n];i++) for(int j=0;j<power[n];j++) a[i][j]=' '; change(n,0,0); for(int i=power[n]-1;i>=0;i--) { for(int j=power[n]-1;j>=0;j--) if(a[i][j]=='O') { a[i][j+1]='\0'; break; } } for(int i=0;i<power[n];i++) { for(int j=0;a[i][j]!='\0';j++) printf("%c",a[i][j]); printf("\n"); } } return 0; }
H 方块与收纳盒
斐波那契数列 只要想清楚这点
N的情况 是 (N-1的所有情况加一个1*1的方块) 和 (N-2的所有情况加一个1*2的方块) 的总和
I 找数字个数
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <bits/stdc++.h> using namespace std; int main() { int t; scanf("%d",&t); while(t--) { int flag[10],cnt=0; memset(flag,0,sizeof(flag)); int a,b; scanf("%d%d",&a,&b); int m,n; m=a,n=b; while(m) { flag[m%10]=1; m/=10; } while(n) { flag[n%10]=1; n/=10; } for(int num=1;num<=1000;num++) { if(num%a==0||num%b==0) continue; int j=num; while(j) { if(flag[j%10]==1) break; j/=10; } if(j) continue; cnt++; } printf("%d\n",cnt); } return 0; }
J 闯关的lulu
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <bits/stdc++.h> using namespace std; int main() { int t; scanf("%d",&t); while(t--) { int n,c=0; scanf("%d",&n); int ans[10]; memset(ans,0,sizeof(ans)); n=n+(n/2)*2; while(n) { if(n%(c+2)==0) ans[c]=0; else { ans[c]=n%(c+2); ans[c+1]=n/(c+2); } n/=(c+2); c++; } for(int i=c;i>=0;i--) { for(int j=0;j<ans[i];j++) printf("%d",i); } printf("\n"); } return 0; }
思路来自 http://blog.csdn.net/qq_40644471/article/details/79130220
以后请一定记住
打比赛不要死磕一道题