2014上海邀请赛
Problem A. Game with pearls http://acmoj.shu.edu.cn/openjudge/viewproblem.php?coll_id=1&prob_id=350
贪心,每次选最小,看能否满足,用优先队列维护。
1 #include<cstdio> 2 #include<queue> 3 using namespace std; 4 struct G{ 5 int val; 6 friend bool operator <(G a,G b){ 7 return a.val>b.val; 8 } 9 }now; 10 priority_queue<G> q; 11 int main(){ 12 int t,n,k,x; 13 while(~scanf("%d",&t)){ 14 while(t--){ 15 scanf("%d%d",&n,&k); 16 while(!q.empty()) q.pop(); 17 for(int i=0;i<n;i++){ 18 scanf("%d",&x); 19 now.val=x; 20 q.push(now); 21 } 22 bool ans=true; 23 for(int i=1;i<=n;i++){ 24 bool flag=false; 25 while(!q.empty()){ 26 now=q.top(); 27 q.pop(); 28 if(now.val>i){ 29 break; 30 } 31 while(true){ 32 if(now.val>=i) break; 33 now.val+=k; 34 } 35 if(now.val==i){ 36 flag=true; 37 break; 38 } 39 q.push(now); 40 } 41 if(!flag){ 42 ans=false; 43 break; 44 } 45 } 46 if(ans) puts("Jerry"); 47 else puts("Tom"); 48 } 49 } 50 return 0; 51 }
Problem C. Seam Carving http://acmoj.shu.edu.cn/openjudge/viewproblem.php?coll_id=1&prob_id=352
dp求二维数组一列和最小,并记录路径,优先选右侧的点,dp[i][j]=max(dp[i-1][j+1],dp[i-1][j],dp[i-1][j-1])+a[i][j];
1 #include<cstdio> 2 #include<cstring> 3 #define mt(a,b) memset(a,b,sizeof(a)) 4 const int inf=0x3f3f3f3f; 5 const int M=128; 6 int a[M][M]; 7 int dp[M][M]; 8 int pre[M][M]; 9 int dy[]={1,0,-1}; 10 int ans[M]; 11 int main(){ 12 int t,n,m; 13 while(~scanf("%d",&t)){ 14 int cas=1; 15 while(t--){ 16 scanf("%d%d",&n,&m); 17 mt(dp,0); 18 for(int i=1;i<=n;i++){ 19 for(int j=1;j<=m;j++){ 20 scanf("%d",&a[i][j]); 21 dp[i][j]=inf; 22 } 23 } 24 mt(pre,-1); 25 for(int i=1;i<=n;i++){ 26 for(int j=1;j<=m;j++){ 27 for(int k=0;k<3;k++){ 28 int ty=j+dy[k]; 29 if(ty>=1&&ty<=m){ 30 if(dp[i][j]>dp[i-1][ty]+a[i][j]){ 31 dp[i][j]=dp[i-1][ty]+a[i][j]; 32 pre[i][j]=k; 33 } 34 } 35 } 36 } 37 } 38 int sma=inf; 39 int id=-1; 40 for(int i=1;i<=m;i++){ 41 if(sma>=dp[n][i]){ 42 sma=dp[n][i]; 43 id=i; 44 } 45 } 46 int nx=n,ny=id,la=0; 47 while(~pre[nx][ny]){ 48 ans[la++]=ny; 49 int k=pre[nx][ny]; 50 ny+=dy[k]; 51 nx--; 52 } 53 printf("Case %d\n",cas++); 54 for(int i=la-1;i>=0;i--){ 55 if(i!=la-1) printf(" "); 56 printf("%d",ans[i]); 57 } 58 puts(""); 59 } 60 } 61 return 0; 62 }
Problem D. Battle ships http://acmoj.shu.edu.cn/openjudge/viewproblem.php?coll_id=1&prob_id=353
竟然是二分图匹配,巧妙的标号和匹配。
1 #include<cstdio> 2 #include<cstring> 3 #define mt(a,b) memset(a,b,sizeof(a)) 4 const int M=3000; 5 char a[M][M]; 6 int heng[M][M]; 7 int shu[M][M]; 8 class Bipartite_graph { //二分图最大匹配 匈牙利算法 9 bool mat[M][M],vis[M]; 10 int res[M],n,m,big; 11 bool dfs(int a) { 12 for (int i=1; i<=m; i++) { 13 if (mat[a][i]&&!vis[i]) { 14 vis[i]=true; 15 if(!res[i]||dfs(res[i])) { 16 res[i]=a; 17 return true; 18 } 19 } 20 } 21 return false; 22 } 23 public: 24 void init(int x,int y) { 25 n=x; 26 m=y; 27 mt(mat,0); 28 mt(res,0); 29 } 30 void add(int u,int v) { 31 mat[u][v]=true; 32 } 33 int solve() { 34 big=0; 35 for(int i=1; i<=n; i++) { 36 mt(vis,0); 37 if(dfs(i)) big++; 38 } 39 return big; 40 } 41 } gx; 42 int main(){ 43 int t,n,m; 44 while(~scanf("%d",&t)){ 45 while(t--){ 46 scanf("%d%d",&m,&n); 47 for(int i=0;i<m;i++){ 48 scanf("%s",a[i]); 49 } 50 mt(heng,0); 51 mt(shu,0); 52 int cnt=1; 53 for(int i=0;i<m;i++){ 54 for(int j=0;j<n;j++){ 55 if(a[i][j]=='*'){ 56 heng[i][j]=cnt; 57 } 58 else if(a[i][j]=='#'){ 59 cnt++; 60 } 61 } 62 cnt++; 63 } 64 int pre=-1; 65 cnt=0; 66 for(int i=0;i<m;i++){ 67 for(int j=0;j<n;j++){ 68 if(heng[i][j]){ 69 if(heng[i][j]==pre){ 70 heng[i][j]=cnt; 71 } 72 else{ 73 cnt++; 74 pre=heng[i][j]; 75 heng[i][j]=cnt; 76 } 77 } 78 } 79 } 80 int nn=cnt; 81 cnt=1; 82 for(int j=0;j<n;j++){ 83 for(int i=0;i<m;i++){ 84 if(a[i][j]=='*'){ 85 shu[i][j]=cnt; 86 } 87 else if(a[i][j]=='#'){ 88 cnt++; 89 } 90 } 91 cnt++; 92 } 93 pre=-1,cnt=0; 94 for(int j=0;j<n;j++){ 95 for(int i=0;i<m;i++){ 96 if(shu[i][j]){ 97 if(shu[i][j]==pre){ 98 shu[i][j]=cnt; 99 } 100 else{ 101 cnt++; 102 pre=shu[i][j]; 103 shu[i][j]=cnt; 104 } 105 } 106 } 107 } 108 gx.init(nn,cnt); 109 for(int i=0;i<m;i++){ 110 for(int j=0;j<n;j++){ 111 if(heng[i][j]&&shu[i][j]){ 112 gx.add(heng[i][j],shu[i][j]); 113 } 114 } 115 } 116 printf("%d\n",gx.solve()); 117 } 118 } 119 return 0; 120 }
Problem F. Linearization of the kernel functions in SVM http://acmoj.shu.edu.cn/openjudge/viewproblem.php?coll_id=1&prob_id=355
模拟输出,无算法,有细节。
1 #include<cstdio> 2 int a[16]; 3 char op[]={"pqruvwxyz"}; 4 int main(){ 5 int n; 6 while(~scanf("%d",&n)){ 7 while(n--){ 8 for(int i=0;i<10;i++){ 9 scanf("%d",&a[i]); 10 } 11 bool flag=false; 12 for(int i=0;i<9;i++){ 13 if(a[i]){ 14 if(flag&&a[i]>0) printf("+"); 15 if(a[i]==-1) printf("-"); 16 if(a[i]!=-1&&a[i]!=1) printf("%d",a[i]); 17 putchar(op[i]); 18 flag=true; 19 } 20 } 21 if(a[9]){ 22 if(flag&&a[9]>0) printf("+"); 23 printf("%d",a[9]); 24 flag=true; 25 } 26 if(!flag) printf("0"); 27 puts(""); 28 } 29 } 30 return 0; 31 }
Problem J. Comparison of Android versions http://acmoj.shu.edu.cn/openjudge/viewproblem.php?coll_id=1&prob_id=359
模拟比较,无算法,无细节。
1 #include<cstdio> 2 #include<cstring> 3 const int M=16; 4 char a[M],b[M],cma[M],cmb[M]; 5 char op[]={"<=>"}; 6 int main(){ 7 int n; 8 while(~scanf("%d",&n)){ 9 for(int i=1;i<=n;i++){ 10 scanf("%s%s",a,b); 11 printf("Case %d: ",i); 12 cma[0]=a[0]; 13 cmb[0]=b[0]; 14 cma[1]=0; 15 cmb[1]=0; 16 printf("%c ",op[1+strcmp(cma,cmb)]); 17 int la=0,lb=0; 18 for(int j=2;j<5;j++){ 19 cma[la++]=a[j]; 20 cmb[lb++]=b[j]; 21 } 22 if(a[1]==b[1]){ 23 cma[la++]=a[5]; 24 cmb[lb++]=b[5]; 25 } 26 cma[la]=0; 27 cmb[lb]=0; 28 printf("%c\n",op[1+strcmp(cma,cmb)]); 29 } 30 } 31 return 0; 32 }