首页 > 代码库 > 山东省第一届acm程序设计竞赛题解

山东省第一届acm程序设计竞赛题解

缺c 计算几何没看 f一个模拟,不想写,难度不大,J,因为时间挺早的,题目都比较简单,没什么难度,组队出个8题还是轻松的

A:水题

技术分享
 1 #include<bits/stdc++.h> 2 using namespace std; 3 const int maxn=1e3+5; 4 string s[maxn]; 5  6 bool judge(string s1,string s2){ 7     if(s1.length()>s2.length())return 1; 8     int len=s1.length(); 9     for(int i=0;i<len;i++)10         if(s1[i]!=s2[i])11             return true;12     return false;13 }14 15 int main(){16     int n;17     while(cin>>n,n){18         bool ok=1;19         for(int i=0;i<n;i++)cin>>s[i];20         21         for(int i=0;i<n;i++)22             for(int j=i+1;j<n;j++)23                 if(judge(s[i],s[j])&&judge(s[j],s[i]))24                     continue;25                 else {26                     ok=0;break;27                 }28         29         if(ok)puts("YES");30         else puts("NO");31         32     }33     return 0;34 }
View Code

b:输出4联通和8联通的联通快数,水题

技术分享
 1 #include<bits/stdc++.h> 2 using namespace std; 3 const int maxn=105; 4 const int dx[]={0,0,1,-1,-1,1,-1,1}; 5 const int dy[]={1,-1,0,0,1,1,-1,-1}; 6 char g[maxn][maxn]; 7 int v[maxn][maxn],n; 8  9 inline bool judge(int x,int y){10     if(x<0||x>=n||y<0||y>=n||g[x][y]==0)return true;11     return false;12 }13 14 void dfs(int x,int y,int t){15     if(v[x][y])return ;16     v[x][y]=1;17     for(int i=0;i<t;i++){18         int nx=x+dx[i];19         int ny=y+dy[i];20         if(judge(nx,ny))continue;21         dfs(nx,ny,t);22     }23 }24 25 26 int main(){27     int cas=1;28     while(~scanf("%d",&n),n){29         for(int i=0;i<n;i++)scanf("%s",g[i]);30         memset(v,0,sizeof(v));31         32         int res1=0,res2=0;33         for(int i=0;i<n;i++)for(int j=0;j<n;j++){34             if(g[i][j]==0)continue;35             if(!v[i][j])res1++;36             dfs(i,j,4);37         }38         memset(v,0,sizeof(v));39         for(int i=0;i<n;i++)for(int j=0;j<n;j++){40             if(g[i][j]==0)continue;41             if(!v[i][j])res2++;42             dfs(i,j,8);43         }44         printf("Case %d: %d %d\n",cas++,res1,res2);45         puts("");46     }47     return 0;48 }
View Code

d.排下序,水题

技术分享
 1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 const int maxn=1e5+5; 5 int d[maxn]; 6  7 int main(){ 8     int n; 9     while(cin>>n,n){10         for(int i=0;i<n;i++)cin>>d[i];11         sort(d,d+n);12         ll res=d[n-1]-d[0];13         14         for(int i=1;i<n;i++)res+=d[i]-d[i-1];15         cout<<res<<endl;16     }17     return 0;18 }
View Code

E:n个城市都沦陷了,有两种操作0 x占领x,1 x y,输出x y的最短路

因为每个点只会被占领一次,只要用这个点来更新其他点就好

技术分享
 1 #include<iostream> 2 #include<cmath> 3 #include<string.h> 4 #include<stdio.h> 5 #define INT_MAX 100000 6 using namespace std; 7 int n,m,q; 8 int map[310][310],vis[310]; 9 void floyd(int k){10     int i,j;11     for(i=0;i<n;i++)12         for(j=0;j<n;j++)13     {14         if((map[i][k]!=INT_MAX) && (map[k][j]!=INT_MAX))15         if(map[i][j]>map[i][k]+map[k][j])16             map[i][j]=map[i][k]+map[k][j];17     }18 }19 void init()20 {21     int i,j;22     for(i=0;i<310;i++){23         for(j=0;j<310;j++)24             map[i][j]=INT_MAX;25         map[i][i]=0;26     }27 }28 int main()29 {30     int i,j,k,l,x,y,z,d,c=0;31     while(cin>>n>>m>>q&&(n||m||q))32     {33         init();34         memset(vis,0,sizeof(vis));35         for(int i=0;i<m;i++){36             cin>>x>>y>>z;37             if(map[x][y]>z)38                 map[x][y]=z;39         }40         printf("Case %d:\n",++c);41         for(j=0;j<q;j++){42             cin>>d;43             if(!d){44                 cin>>x;45                 if(!vis[x]){46                     vis[x]=1;47                     floyd(x);48                 }49                 else printf("City %d is already recaptured.\n",x);50             }51             else{52                 cin>>x>>y;53                 if(!vis[x]||!vis[y])54                     printf("City %d or %d is not available.\n",x,y);55                 else if(map[x][y]==INT_MAX)56                     cout<<"No such path."<<endl;57                 else cout<<map[x][y]<<endl;58             }59         }60         cout<<endl;61     }62     return 0;63 }
View Code

F:模拟题,题意难读,不过好写,110行就差不多能写完

G:n个数,从中取四个数,每个数可以重复取,输出小于等于M的最大值

先把两个数和的存下来,排个序,然后双指针就Ok

技术分享
 1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 const int maxn=1e3+5; 5 int d[maxn],c[maxn*maxn]; 6 int n,m; 7  8 int main(){ 9     int cas=1;10     while(cin>>n>>m,n){11         for(int i=0;i<n;i++)cin>>d[i];12         int cnt=0;13         for(int i=0;i<n;i++)for(int j=0;j<n;j++)14             c[cnt++]=d[i]+d[j];15         16         sort(c,c+cnt);17         18         int l=0,r=cnt-1;19         ll res=0;20         while(c[r]>m)r--;21         22         while(l<=r){23             if((ll)c[l]+c[r]>m)r--;24             else {25                 res=max(res,(ll)c[l]+c[r]);26                 l++;27             }28             if(res==m)break;29         }30         printf("Case %d: %lld\n\n",cas++,res);31     }32     return 0;33 }
View Code

H:输出在(x,y)右边以及下面的第一个点,具体要求看题目

n只有300,直接爆

技术分享
 1 #include<bits/stdc++.h> 2 using namespace std; 3 const int maxn=1005; 4 int x[maxn],y[maxn],z[maxn]; 5  6 int main(){ 7     int n,cas=1; 8     while(cin>>n,n){ 9         for(int i=0;i<n;i++)cin>>x[i]>>y[i],z[i];10         11         int nx,ny;12         printf("Case %d:\n",cas++);13         for(int i=0;i<n;i++){14             nx=ny=-1;15             for(int j=0;j<n;j++)16                 if(x[j]>x[i]&&y[j]>y[i]){17                     if(nx==-1)nx=x[j],ny=y[j];18                     else if(x[j]<nx)nx=x[j],ny=y[j];19                     else if(x[j]==nx&&y[j]<ny)ny=y[j];20                 }21             printf("%d %d\n",nx,ny);22         }23         puts("");24     }25     return 0;26 }
View Code

I:上一题的加强版,可以加入一个点,删除一个点,然后查询一个点的右下方点,要求和上面一样

分析:讲道理写了个AVL插入两个元素应该没问题,迷之超时,set套pair,找到第然后二分找一下点,然后符合要求的肯定在后面,找到第一个点就好了

J:题目太长,没看

山东省第一届acm程序设计竞赛题解