官方题解:http://blog.sina.com.cn/duoxiao2015
队友回家了。。于是开启单刷模式。。。但是中间吃饭+被叫去开会,于是比赛时就AC了3题,排167名,开完会回来继续把第4题写完,结果刚好比赛结束,于是就变成赛后AC
HDOJ5327
题意:问[l,r]中有几个数是各个位的数字均不相同
思路:水题,先预处理下就好
#include <algorithm> #include <iostream> #include <cstring> #include <cstdio> #include <cmath> using namespace std; typedef long long LL; const int MAXN=100000+10; int T,n,m,k,l,r; int a[MAXN]; bool fun(int x){ bool num[15]={0}; while(x){ int c=x%10; if(num[c])return 0; else num[c]=1; x/=10; } return 1; } void init(){ a[0]=0; for(int i=1;i<MAXN;i++){ a[i]=a[i-1]; if(fun(i))a[i]++; } //memset(a,0,sizeof(a)); } void work(){} int main(){ #ifdef DEBUG freopen("CBin.txt","r",stdin); //freopen("CBout.txt","w",stdout); #endif init(); cin>>T; while(T--){ cin>>l>>r; cout<<a[r]-a[l-1]<<"\n"; } return 0; }
HDOJ5328
题意:给一个长为n的序列,问能形成等差数列或者等比数列的连续子序列最长为多少
思路:水题,但不知为何我O(n)的方法会超时,加上快速读入就过了。。。
#include <algorithm> #include <iostream> #include <cstring> #include <cstdio> #include <cmath> using namespace std; typedef long long LL; const int MAXN=1000000+10; const int INF=1e9*2; const double eps=1e-9; int T,n,m,k,l,r; int a[MAXN]; void init(){ //memset(a,0,sizeof(a)); } int work(){ int ap=INF,ka=1,kg=1,k; double gp=INF; if(n>1){ap=a[1]-a[0];ka++;} if(n>1&&a[0]!=0){gp=1.0*a[1]/a[0];kg++;} k=max(ka,kg); for(int i=2;i<n;i++){ int nap=a[i]-a[i-1]; if(nap==ap)ka++; else{ ap=nap; k=max(ka,k); ka=2; } double ngp; if(a[i]!=0){ ngp=1.0*a[i]/a[i-1]; if(abs(ngp-gp)<eps)kg++; else{ gp=ngp; k=max(kg,k); kg=2; } }else{ gp=INF; kg=1; } } k=max(k,ka); k=max(k,kg); return k; } template <class T> inline bool read(T &ret) { char c; int sgn; if(c=getchar(),c==EOF) return 0; //EOF while(c!='-'&&(c<'0'||c>'9')) c=getchar(); sgn=(c=='-')?-1:1; ret=(c=='-')?0:(c-'0'); while(c=getchar(),c>='0'&&c<='9') ret=ret*10+(c-'0'); ret*=sgn; return 1; } int main(){ #ifdef DEBUG freopen("CBin.txt","r",stdin); //freopen("CBout.txt","w",stdout); #endif cin>>T; while(T--){ init(); read(n); if(n==0){cout<<"0\n";continue;} for(int i=0;i<n;i++)read(a[i]); //putchar(work()+'0'); cout<<work()<<"\n"; } return 0; }
HDOJ5335
题意:给一个n*m大小,且仅有01的图,问从左上到右下所经过的路径连起来所代表的二进制最小为多少
思路: 先bfs找到距离右下最近且与左上仅由0相连的0,再从这些0出发进行bfs,剪枝剪掉肯定不为最小的路径,bfs时记录方向,最后找出这条路径并输出结果
#include <algorithm> #include <iostream> #include <cstring> #include <cstdio> #include <cmath> #include <queue> using namespace std; typedef long long LL; const int MAXN=1000+10; int T,n,m; bool g[MAXN][MAXN],vis[MAXN][MAXN]; int dis[MAXN][MAXN],disf[5][2]={{0,0},{0,1},{1,0},{0,-1},{-1,0}}; bool res[MAXN<<1]; int p; void init(){ getchar(); for (int i=0;i<n;++i){ for (int j=0;j<m;++j){ char c=getchar(); g[i][j]=c-'0'; } getchar(); } memset(dis,0,sizeof(dis)); memset(vis,0,sizeof(vis)); } bool check(int x,int y){ if(x<0||y<0||x>=n||y>=m)return 0; else return 1; } int bfs1(){ queue<int>q; int now,x,y,k=0; if(g[0][0]==1)return 0; q.push(0); while(!q.empty()){ now=q.front(); x=now/m; y=now%m; for(int i=1;i<=4;i++){ int nx=x+disf[i][0]; int ny=y+disf[i][1]; if(check(nx,ny)&&!g[nx][ny]&&!dis[nx][ny]){ dis[nx][ny]=i; q.push(nx*m+ny); } } k=max(k,x+y); q.pop(); } return k; } void bfs2(int k){ queue<int>q; queue<int>q2[2]; int now,x,y; if(k==0)q.push(0); else for(int i=0;i<=k;i++){ x=i; y=k-i; if(check(x,y)&&dis[x][y])q.push(x*m+y); } while(1){ while(!q.empty()){ now=q.front(); x=now/m; y=now%m; for(int i=1;i<=2;i++){ int nx=x+disf[i][0]; int ny=y+disf[i][1]; if(check(nx,ny)&&!dis[nx][ny]){ dis[nx][ny]=i; q2[g[nx][ny]].push(nx*m+ny); } } q.pop(); } if(q2[0].empty()&&q2[1].empty())break; if(q2[0].empty()){ while(!q2[1].empty()){ q.push(q2[1].front()); q2[1].pop(); } }else { while(!q2[1].empty())q2[1].pop(); while(!q2[0].empty()){ q.push(q2[0].front()); q2[0].pop(); } } } } void disp(int k){ int x=n-1,y=m-1; memset(res,0,sizeof(res)); p=0; for(int i=n+m-2;i>=k;i--){ res[p++]=g[x][y]; int f=dis[x][y]; x-=disf[f][0]; y-=disf[f][1]; } p--; if(res[p])printf("%d",res[p]); p--; for(;p>=0;p--){ printf("%d",res[p]); } printf("\n"); } int main(){ #ifdef DEBUG freopen("CBin.txt","r",stdin); //freopen("CBout.txt","w",stdout); #endif cin>>T; while(T--){ cin>>n>>m; init(); int k=bfs1(); if(k==0&&n==1&&m==1){cout<<g[0][0]<<"\n";continue;} if(k==n+m-2){cout<<"0\n";continue;} bfs2(k); disp(k); } return 0; }
HDOJ5536
题意:就是给你r*c的图,图上有n个水滴,告诉你每个水滴的坐标以及水滴的大小,在xy处有个水滴爆炸,问第T秒时各个水滴的状态,已经爆炸输出0和爆炸时间,未爆输出1和第T秒时的大小
爆炸与变大的游戏规则就是十滴水那款小游戏的规则,有玩过的就可以直接跳过规则说明部分
规则:水滴爆炸时该位置水滴消失并向4个方向发射一个小水滴,每个运动的小水滴与静止的水滴碰撞则会融合,融合后的大小为原大小加1,如果大于4,则该位置发生爆炸
思路:暴力模拟
#include <algorithm> #include <iostream> #include <cstring> #include <cstdio> #include <cmath> #include <queue> using namespace std; typedef long long LL; const int MAXN=100+10; int T,n,m,time,num; int g[MAXN][MAXN],gt[MAXN][MAXN]; int disf[5][2]={{0,0},{0,1},{1,0},{0,-1},{-1,0}}; int x,y; struct Point{ int x; int y; }poi[MAXN]; struct Move{ int x; int y; int disx; int disy; }; template <class T> inline bool read(T &ret) { char c; int sgn; if(c=getchar(),c==EOF) return 0; //EOF while(c!='-'&&(c<'0'||c>'9')) c=getchar(); sgn=(c=='-')?-1:1; ret=(c=='-')?0:(c-'0'); while(c=getchar(),c>='0'&&c<='9') ret=ret*10+(c-'0'); ret*=sgn; return 1; } void init(){ memset(g,0,sizeof(g)); memset(gt,0,sizeof(gt)); for(int i=0;i<num;i++){ int x,y,c; read(x); read(y); read(c); g[x][y]=c; poi[i]=(Point){x,y}; } read(x); read(y); } bool check(int x,int y){ if(x<=0||y<=0||x>n||y>m)return 0; else return 1; } void bfs(){ queue<Move>q[2]; queue<Point>p; int f=0; int t=0; q[f].push((Move){x,y,1,0}); q[f].push((Move){x,y,-1,0}); q[f].push((Move){x,y,0,1}); q[f].push((Move){x,y,0,-1}); while(1){ t++; while(!q[f].empty()){ Move now=q[f].front(); int x=now.x+now.disx; int y=now.y+now.disy; if(check(x,y)){ if(g[x][y]){ g[x][y]++; p.push((Point){x,y}); } else{ now.x=x; now.y=y; q[f^1].push(now); } } q[f].pop(); } while(!p.empty()){ Point now=p.front(); int x=now.x; int y=now.y; if(g[x][y]>4){ g[x][y]=0; gt[x][y]=t; q[f^1].push((Move){x,y,1,0}); q[f^1].push((Move){x,y,-1,0}); q[f^1].push((Move){x,y,0,1}); q[f^1].push((Move){x,y,0,-1}); } p.pop(); } f^=1; if(q[f].empty())break; if(t>=time)break; } } int main(){ #ifdef DEBUG freopen("CBin.txt","r",stdin); //freopen("CBout.txt","w",stdout); #endif while(~scanf("%d%d%d%d",&n,&m,&num,&time)){ init(); bfs(); for(int i=0;i<num;i++){ if(gt[poi[i].x][poi[i].y]){ printf("0 %d\n",gt[poi[i].x][poi[i].y]); }else{ printf("1 %d\n",g[poi[i].x][poi[i].y]); } } } return 0; }