题目链接:http://acm.hdu.edu.cn/diy/contest_show.php?cid=34362
题目比较水(有难度的1003,1007,1008)
1001,模拟,理解题意,排序找就行。0的话特殊考虑也是麻烦的一种,不为0就简单了,一个循环找下去记录就行。
1 #include <iostream> 2 #include <string> 3 #include <algorithm> 4 #include <cstdio> 5 #include <cstring> 6 using namespace std; 7 typedef long long ll; 8 const int maxn=1e6+5; 9 ll a[maxn]; 10 ll t[maxn]; 11 ll n; 12 13 ll getcner(ll n) 14 { 15 n=n-1; 16 ll s=n*(1+n)/2; 17 18 return s; 19 } 20 21 int main() 22 { 23 ios::sync_with_stdio(false); cin.tie(0); 24 25 int T; 26 cin>>T; 27 while(T--) 28 { 29 memset(t,0,sizeof(t)); 30 31 cin>>n; 32 for(int i=1;i<=n;i++) cin>>a[i]; 33 34 sort(a+1,a+1+n); 35 ll Min=1e9+5; 36 for(int i=2;i<=n;i++) 37 { 38 Min=min(Min,a[i]-a[i-1]); 39 } 40 if(Min==0) 41 { 42 ll last=a[1]; 43 int p=1; 44 for(int i=2;i<=n;i++) 45 { 46 if(a[i]==last) t[p]++; 47 else 48 { 49 last=a[i]; 50 p++; 51 } 52 } 53 54 ll cnt=0; 55 for(int i=1;i<=p-1;i++) 56 { 57 cnt+=getcner(t[i]+1); 58 } 59 if(t[p]) cnt+=getcner(t[p]+1); 60 61 cout<<Min<<' '<<cnt<<endl; 62 } 63 else 64 { 65 ll cnt=0; 66 for(int i=2;i<=n;i++) 67 { 68 if(a[i]-a[i-1]==Min) cnt++; 69 } 70 71 cout<<Min<<' '<<cnt<<endl; 72 } 73 } 74 75 return 0; 76 }
1002,简单题,模拟即可。用map和string会好做些。
1 #include <iostream> 2 #include <string> 3 #include <map> 4 using namespace std; 5 map<int,string> mp; 6 string s[53]; 7 8 int main() 9 { 10 11 int p=0; 12 char c=64; 13 for(int i=1;i<=4;i++) 14 { 15 c++; 16 for(int j=1;j<=13;j++) 17 { 18 if(j<=9) 19 { 20 char t=j+'0'; 21 22 string z=""; 23 z=z+c; 24 z=z+t; 25 26 mp[++p]=z; 27 } 28 else 29 { 30 string t; 31 if(j==10) t="10"; 32 else if(j==11) t="J"; 33 else if(j==12) t="Q"; 34 else if(j==13) t="K"; 35 36 string z=""; 37 z=z+c; 38 z=z+t; 39 40 mp[++p]=z; 41 } 42 } 43 } 44 45 46 int T; 47 cin>>T; 48 while(T--) 49 { 50 for(int i=1;i<=51;i++) cin>>s[i]; 51 52 int f=0; 53 for(int i=1;i<=51;i++) 54 { 55 if(mp[i]!=s[i]) 56 { 57 f=i; 58 break; 59 } 60 } 61 if(f==0) cout<<mp[52]<<endl; 62 else cout<<mp[f]<<endl; 63 } 64 }
1003,重点,经典二分题最小值最大化,Judge函数略难写,想了好长时间用2个数组写出Judge函数。
1 #include <iostream> 2 #include <string> 3 #include <algorithm> 4 #include <cstdio> 5 #include <cstring> 6 using namespace std; 7 typedef long long ll; 8 const int maxn=1e6+5; 9 ll a[maxn],t[maxn]; 10 int L,N,M; 11 12 ll judge(ll x) 13 { 14 for(int i=1;i<=N;i++) t[i]=a[i]; 15 ll last=t[1],cnt=0; 16 for(int i=1;i<=N-1;i++) 17 { 18 if(t[i]<x) 19 { 20 cnt++; 21 t[i]+=t[i+1]; 22 t[i+1]=t[i]; 23 } 24 //else 25 } 26 if(t[N]<x) cnt++; 27 28 return cnt; 29 } 30 31 int main() 32 { 33 ios::sync_with_stdio(false); cin.tie(0); 34 35 int t; 36 cin>>t; 37 while(t--) 38 { 39 cin>>N>>M; 40 ll l=1e7,sum=0; 41 for(int i=1;i<=N;i++) { cin>>a[i]; sum+=a[i]; l=min(l,a[i]); } 42 43 //sort(a+1,a+1+N); 44 ll r=sum; 45 ll ans=0; 46 while(l<=r) 47 { 48 ll mid=(l+r)/2; 49 50 int t=judge(mid); 51 if(t<=M) 52 { 53 ans=max(ans,mid); 54 l=mid+1; 55 } 56 else r=mid-1; 57 } 58 59 cout<<ans<<endl; 60 } 61 62 return 0; 63 }
1004,找为k的子矩阵,循环或递归找判断下去即可
1 #include <iostream> 2 #include <string> 3 #include <algorithm> 4 #include <cstdio> 5 #include <cstring> 6 #include <cmath> 7 using namespace std; 8 typedef long long llo; 9 const int maxn=1000; 10 int a[maxn][maxn]; 11 int n,m,kk; 12 int f; 13 14 void so(int x,int y,int k) 15 { 16 if(f) return; 17 if(k<0) return; 18 19 for(int j=y;j<=y+k;j++) if(a[x][j]!=0) { f=1; return; } 20 for(int i=x;i<=x+k;i++) if(a[i][y]!=0) { f=1; return; } 21 22 if(f==0 && x+1<=n && y+1<=m) so(x+1,y+1,k-1); 23 24 } 25 26 int main() 27 { 28 ios::sync_with_stdio(false);cin.tie(0); 29 30 31 int T; 32 cin>>T; 33 while(T--) 34 { 35 36 cin>>n>>m>>kk; 37 for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) cin>>a[i][j]; 38 39 for(int i=1;i<=n;i++) 40 { 41 for(int j=1;j<=m;j++) 42 { 43 f=0; 44 if(a[i][j]==0 && i+kk-1<=n && j+kk-1<=m) 45 { 46 so(i,j,kk-1); 47 } 48 else f=1; 49 if(f==0) break; 50 } 51 if(f==0) break; 52 } 53 54 if(f==0) cout<<"Yes"<<endl; 55 else cout<<"No"<<endl; 56 57 } 58 59 return 0; 60 }
1005,题目给你说的绕的超麻烦,看样例或模拟后找到规律即可
1 #include <iostream> 2 #include <string> 3 #include <algorithm> 4 #include <iomanip> 5 #include <cstdio> 6 #include <cstring> 7 #include <cmath> 8 using namespace std; 9 typedef long long ll; 10 typedef unsigned long long ull; 11 const int maxn=1e6+5; 12 int a[maxn]; 13 int t,n; 14 15 int main() 16 { 17 scanf("%d",&t); 18 while(t--) 19 { 20 scanf("%d",&n); 21 for(int i=1;i<=n;i++) scanf("%d",&a[i]); 22 23 sort(a+1,a+1+n); 24 int cnt=0; 25 for(int i=2;i<=n;i++) 26 { 27 if(a[i]==a[i-1]) cnt++; 28 } 29 30 printf("%d ",cnt); 31 } 32 33 return 0; 34 }
1006,排个序,贪心思想走下去即可。从短到长,后一个必须包含前一个才能继续,不用考虑字典序和相等时情况。另外数据小,不用kmp找,string::find函数方便找就行。
1 #include <iostream> 2 #include <string> 3 #include <algorithm> 4 #include <map> 5 using namespace std; 6 7 struct px 8 { 9 string s; 10 int len; 11 }T[1005]; 12 bool cmp(px aa,px bb) 13 { 14 return aa.len<bb.len; 15 } 16 17 int main() 18 { 19 ios::sync_with_stdio(false); cin.tie(0); 20 21 int t; 22 cin>>t; 23 while(t--) 24 { 25 int n; 26 cin>>n; 27 for(int i=1;i<=n;i++) 28 { 29 cin>>T[i].s; 30 31 T[i].len=T[i].s.length(); 32 } 33 34 sort(T+1,T+1+n,cmp); 35 36 int f=0; 37 string last=T[1].s; 38 for(int i=2;i<=n;i++) 39 { 40 if(T[i].s.find(last)!=string::npos) continue; 41 else { f=1; break;} 42 43 last=T[i].s; 44 } 45 if(f) cout<<"No"<<endl; 46 else cout<<"Yes"<<endl; 47 } 48 49 return 0; 50 }
1007,难题,防Ak
1008,重点,搜索题,单纯搜索的很好些,但这题要找到所有的方法,很容易超时!
(这题我历经了三个艰难阶段~~最后知道这是最短路条数模板题
1.最先想到的是dfs搜索所有路,如果没有障碍物那得搜索多少条啊我的天!
2.想了一会又想试试记忆化,但没办法啊它要回溯更新试试更多的路啊你把原先的标记返回了肯定是错的啊。
3.唉没办法,只能用专门的最短路贪心做法Dijkstra了,其实bfs本质就是Dijkstra,只不过权值为1更简单特殊化了!
)
暴力超时代码
1 #include <iostream> 2 #include <string> 3 #include <algorithm> 4 #include <cstdio> 5 #include <cstring> 6 using namespace std; 7 typedef long long ll; 8 const int maxn=1e6+5; 9 const int mod=1000000007; 10 char a[1005][1005]; 11 int vis[1005][1005],f[1005][1005]; 12 int n,m; 13 int gx,gy; 14 int ans; 15 16 void so(int x,int y) 17 { 18 if(x==gx && y==gy) 19 { 20 ans++; 21 ans%=mod; 22 return; 23 } 24 25 //右 26 if(y+1<=m && a[x][y+1]=='.' && vis[x][y+1]==0) { vis[x][y+1]=1; so(x,y+1); vis[x][y+1]=0; } 27 28 //下 29 if(x+1<=n && a[x+1][y]=='.' && vis[x+1][y]==0) { vis[x+1][y]=1; so(x+1,y); vis[x+1][y]=0; } 30 31 //上 32 if(x-1>=1 && a[x-1][y]=='.' && vis[x-1][y]==0) { vis[x-1][y]=1; so(x-1,y); vis[x-1][y]=0; } 33 34 //左 35 if(y-1>=1 && a[x][y-1]=='.' && vis[x][y-1]==0) { vis[x][y-1]=1; so(x,y-1); vis[x][y-1]=0; } 36 } 37 38 int main() 39 { 40 ios::sync_with_stdio(false); cin.tie(0); 41 42 int T; 43 cin>>T; 44 while(T--) 45 { 46 ans=0; 47 cin>>n>>m; 48 for(int i=1;i<=n;i++) 49 { 50 for(int j=1;j<=m;j++) 51 { 52 cin>>a[i][j]; 53 } 54 } 55 cin>>gx>>gy; 56 57 vis[1][1]=1; 58 so(1,1); 59 vis[1][1]=0; 60 61 if(ans) cout<<ans<<endl; 62 else cout<<"-1"<<endl; 63 } 64 65 return 0; 66 }
Ac代码
dijkstra写法
1 #include <iostream> 2 #include <string> 3 #include <algorithm> 4 #include <iomanip> 5 #include <vector> 6 #include <queue> 7 #include <cstdio> 8 #include <cstring> 9 using namespace std; 10 const int maxn=550;//最大点数 11 const int maxm=1e6+5;//最大边数 12 const int inf=2100000000; 13 const int mod=1000000007; 14 int dist[maxn][maxn],vis[maxn][maxn]; 15 int cnt[maxn][maxn]; 16 char maze[maxn][maxn]; 17 int n,m,s; 18 int ans,cntn; 19 int gx,gy; 20 int zh=(gx-1)*m+gy; 21 22 struct px//存图结点信息 23 { 24 int tox; 25 int toy; 26 int w; 27 px(){}; 28 px(int TOX,int TOY,int W):tox(TOX),toy(TOY),w(W){}; 29 }; 30 vector<px> vec[maxn][maxn]; 31 struct pxx//存所有相连的边的信息 32 { 33 int i; 34 int j; 35 int dist; 36 bool operator<(const pxx &a) const 37 { 38 return dist>a.dist; 39 } 40 pxx(){}; 41 pxx(int I,int J,int DIST):i(I),j(J),dist(DIST){}; 42 }; 43 priority_queue<pxx> que; 44 45 void Init() 46 { 47 for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) dist[i][j]=inf; 48 for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) cnt[i][j]=0; 49 memset(vis,0,sizeof(vis)); 50 } 51 52 void Dijkstra(int x,int y) 53 { 54 dist[x][y]=0; 55 que.push(pxx(x,y,0)); 56 cnt[x][y]=1; 57 58 while(!que.empty()) 59 { 60 pxx tmp=que.top(); 61 que.pop(); 62 if(vis[tmp.i][tmp.j]) continue; 63 64 vis[tmp.i][tmp.j]=1; 65 66 cntn++; 67 if(cntn==zh) break; 68 69 for(int j=0;j<vec[tmp.i][tmp.j].size();j++) 70 { 71 int I=vec[tmp.i][tmp.j][j].tox,J=vec[tmp.i][tmp.j][j].toy,W=vec[tmp.i][tmp.j][j].w; 72 if(!vis[I][J]) 73 { 74 if(dist[I][J]>dist[tmp.i][tmp.j]+W) 75 { 76 dist[I][J]=dist[tmp.i][tmp.j]+W; 77 que.push(pxx(I,J,dist[I][J])); 78 79 cnt[I][J]=cnt[tmp.i][tmp.j]%mod; 80 } 81 else if(dist[I][J]==dist[tmp.i][tmp.j]+W) 82 { 83 cnt[I][J]=(cnt[I][J]+cnt[tmp.i][tmp.j])%mod; 84 } 85 } 86 } 87 } 88 } 89 90 int main() 91 { 92 ios::sync_with_stdio(false); cin.tie(0); 93 94 int T; 95 cin>>T; 96 while(T--) 97 { 98 cin>>n>>m; 99 100 Init();//注意初始化无限大必须放在输入之前! 101 cntn=0;//多组输入时也要初始化 102 for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) cin>>maze[i][j]; 103 cin>>gx>>gy; 104 for(int i=1;i<=n;i++) 105 { 106 for(int j=1;j<=m;j++) 107 { 108 if(maze[i][j]=='.') 109 { 110 if(maze[i][j+1]=='.' && j+1<=m) 111 { 112 vec[i][j].push_back(px(i,j+1,1)); 113 } 114 if(maze[i+1][j]=='.' && i+1<=n) 115 { 116 vec[i][j].push_back(px(i+1,j,1)); 117 } 118 119 if(maze[i-1][j]=='.' && i-1>=1) 120 { 121 vec[i][j].push_back(px(i-1,j,1)); 122 } 123 if(maze[i][j-1]=='.' && j-1>=1) 124 { 125 vec[i][j].push_back(px(i,j-1,1)); 126 } 127 } 128 } 129 } 130 131 Dijkstra(1,1); 132 133 //for(int i=1;i<=n-1;i++) cout<<dist[i]<<' '; 134 if(cnt[gx][gy]) cout<<cnt[gx][gy]<<endl; 135 else cout<<"-1"<<endl; 136 137 while(que.size()) que.pop();//多组输入时也要清空 138 for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) vec[i][j].clear(); 139 } 140 141 return 0; 142 }
bfs写法
1 #include <iostream> 2 #include <string> 3 #include <algorithm> 4 #include <iomanip> 5 #include <vector> 6 #include <queue> 7 #include <cstdio> 8 #include <cstring> 9 using namespace std; 10 const int maxn=550;//最大点数 11 const int maxm=1e6+5;//最大边数 12 const int inf=2100000000; 13 const int mod=1000000007; 14 int dist[maxn][maxn],vis[maxn][maxn]; 15 int cnt[maxn][maxn]; 16 int X[4]={0,1,-1,0}; 17 int Y[4]={1,0,0,-1}; 18 char maze[maxn][maxn]; 19 int n,m,s; 20 int ans,cntn; 21 int gx,gy; 22 int zh=(gx-1)*m+gy; 23 24 struct px//存图结点信息 25 { 26 int x; 27 int y; 28 px(){}; 29 px(int X,int Y):x(X),y(Y){}; 30 }; 31 32 queue<px> que; 33 //二维,他就那可能连接的四条边,而且权值还都为1,所以不用再用个结构体优先队列去存了 34 //那些存不定条数和权值很好,但存固定的这种简单的虽然也可以但大材小用了 35 36 void Init() 37 { 38 for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) dist[i][j]=inf; 39 for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) cnt[i][j]=0; 40 memset(vis,0,sizeof(vis)); 41 } 42 43 void bfs(int x,int y) 44 { 45 dist[x][y]=0; 46 que.push(px(x,y)); 47 cnt[x][y]=1; 48 49 while(!que.empty()) 50 { 51 px tmp=que.front(); 52 que.pop(); 53 if(vis[tmp.x][tmp.y]) continue; 54 if(maze[tmp.x][tmp.y]!='.') continue; 55 56 vis[tmp.x][tmp.y]=1; 57 58 cntn++; 59 if(cntn==zh) break;//两种break都可以,推荐1个 60 //if(tmp.x==gx && tmp.y==gy) break; 61 for(int i=0;i<=3;i++) 62 { 63 int I=tmp.x+X[i],J=tmp.y+Y[i]; 64 if(!vis[I][J] && maze[I][J]=='.' && I<=n && J<=m) 65 { 66 if(dist[I][J]>dist[tmp.x][tmp.y]+1) 67 { 68 dist[I][J]=dist[tmp.x][tmp.y]+1; 69 que.push(px(I,J)); 70 71 cnt[I][J]=cnt[tmp.x][tmp.y]%mod; 72 } 73 else if(dist[I][J]==dist[tmp.x][tmp.y]+1) 74 { 75 cnt[I][J]=(cnt[I][J]+cnt[tmp.x][tmp.y])%mod; 76 } 77 } 78 } 79 } 80 } 81 82 int main() 83 { 84 ios::sync_with_stdio(false); cin.tie(0); 85 86 int T; 87 cin>>T; 88 while(T--) 89 { 90 cin>>n>>m; 91 92 Init();//注意初始化无限大必须放在输入之前! 93 cntn=0;//多组输入时也要初始化 94 for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) cin>>maze[i][j]; 95 cin>>gx>>gy; 96 97 bfs(1,1); 98 99 //for(int i=1;i<=n-1;i++) cout<<dist[i]<<' '; 100 if(cnt[gx][gy]) cout<<cnt[gx][gy]<<endl; 101 else cout<<"-1"<<endl; 102 103 while(que.size()) que.pop();//多组输入时也要清空 104 105 } 106 107 return 0; 108 }
完。