2011 Asia Fuzhou Regional Contest
Xiangqi http://acm.hdu.edu.cn/showproblem.php?pid=4121
模拟,用高内聚低耦合的思想来写模拟题还是很好的,提高了函数的可重用性,程序的可读性,正确性,总而言之,写函数麻烦,总比debug麻烦来的好。
1 #include<cstdio> 2 const int M=16; 3 struct point{ 4 int x,y; 5 }p[M]; 6 char has[M][M],op[M]; 7 bool vis[M][M]; 8 int dx[]={-1,1,0,0}; 9 int dy[]={0,0,-1,1}; 10 bool insidemap(const point &a){ 11 if(a.x>=1&&a.x<=10&&a.y>=1&&a.y<=9) return true;return false; 12 } 13 void flag(const point &a){ 14 vis[a.x][a.y]=true; 15 } 16 bool had(const point &a){ 17 if(has[a.x][a.y]!='.') return true;return false; 18 } 19 void step(point &a,int dir){ 20 a.x+=dx[dir]; 21 a.y+=dy[dir]; 22 } 23 void solveG(point a){ 24 while(true){ 25 step(a,0); 26 if(!insidemap(a)) return ; 27 flag(a); 28 if(had(a)) return ; 29 } 30 } 31 void solveR(const point &b){ 32 for(int i=0;i<4;i++){ 33 point a=b; 34 while(true){ 35 step(a,i); 36 if(!insidemap(a)) break; 37 flag(a); 38 if(had(a)) break; 39 } 40 } 41 } 42 void solveH(const point &b){ 43 for(int i=0;i<4;i++){ 44 point a=b; 45 step(a,i); 46 if(had(a)) continue; 47 step(a,i); 48 if(i<2){ 49 for(int j=2;j<4;j++){ 50 point c=a; 51 step(c,j); 52 if(insidemap(c)) flag(c); 53 } 54 } 55 else{ 56 for(int j=0;j<2;j++){ 57 point c=a; 58 step(c,j); 59 if(insidemap(c)) flag(c); 60 } 61 } 62 } 63 } 64 void solveC(const point &b){ 65 for(int i=0;i<4;i++){ 66 point a=b; 67 while(true){ 68 step(a,i); 69 if(!insidemap(a)||had(a)) break; 70 } 71 while(true){ 72 step(a,i); 73 if(!insidemap(a)) break; 74 flag(a); 75 if(had(a)) break; 76 } 77 } 78 } 79 bool insidehouse(const point &a){ 80 if(a.x>=1&&a.x<=3&&a.y>=4&&a.y<=6) return true;return false; 81 } 82 bool judge(const point &b){ 83 for(int i=0;i<4;i++){ 84 point a=b; 85 step(a,i); 86 if(insidehouse(a)&&!vis[a.x][a.y]) return false; 87 } 88 return true; 89 } 90 int main(){ 91 int n; 92 while(~scanf("%d%d%d",&n,&p[0].x,&p[0].y),n|p[0].x|p[0].y){ 93 for(int i=1;i<=10;i++){ 94 for(int j=1;j<=9;j++){ 95 has[i][j]='.'; 96 vis[i][j]=false; 97 } 98 } 99 for(int i=1;i<=n;i++){ 100 scanf("%s%d%d",op,&p[i].x,&p[i].y); 101 has[p[i].x][p[i].y]=op[0]; 102 } 103 for(int i=1;i<=n;i++){ 104 op[0]=has[p[i].x][p[i].y]; 105 if(op[0]=='G'){ 106 solveG(p[i]); 107 } 108 else if(op[0]=='R'){ 109 solveR(p[i]); 110 } 111 else if(op[0]=='H'){ 112 solveH(p[i]); 113 } 114 else{ 115 solveC(p[i]); 116 } 117 } 118 puts(judge(p[0])?"YES":"NO"); 119 } 120 return 0; 121 }
Alice's mooncake shop http://acm.hdu.edu.cn/showproblem.php?pid=4122
订单按顺序来,然后对第一个订单,暴力算,然后记录一下最小的id,第二个就可以从上一个订单时刻往后找,因为前面已经找过了,单调队列的思想。
1 #include<cstdio> 2 #include<cstring> 3 typedef __int64 LL; 4 const LL inf=0x3f3f3f3f3f3f3f3fLL; 5 const int M=32; 6 struct Date { 7 int year, month, day; 8 }now; 9 int days[12]= {31,28,31,30,31,30,31,31,30,31,30,31}; //日期函数 10 class DATE { 11 public: 12 int leap(int year) { //判闰年 13 return (year%4==0&&year%100!=0)||year%400==0; 14 } 15 int date2int(Date a) { //日期转天数偏移 16 int ret=a.year*365+(a.year-1)/4-(a.year-1)/100+(a.year-1)/400; 17 days[1]+=leap(a.year); 18 for(int i=0; i<a.month-1; ret+=days[i++]); 19 days[1]=28; 20 return ret+a.day; 21 } 22 } help; 23 char yuefen[M][M]={"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov" , "Dec"}; 24 char month[M]; 25 struct IN{ 26 LL time,R; 27 }in[3000]; 28 int cost[100010]; 29 int main(){ 30 int n,m,data,year,H,R; 31 LL T,S; 32 now.year=2000; 33 now.month=now.day=1; 34 int preday=help.date2int(now); 35 while(~scanf("%d%d",&n,&m),n|m){ 36 int s=1,t=1; 37 for(int i=0;i<n;i++){ 38 scanf("%s%d%d%d%I64d",month,&now.day,&now.year,&H,&in[i].R); 39 for(int j=0;j<12;j++){ 40 if(!strcmp(yuefen[j],month)){ 41 now.month=j+1; 42 break; 43 } 44 } 45 in[i].time=(help.date2int(now)-preday)*24+H+1; 46 } 47 scanf("%I64d%I64d",&T,&S); 48 for(int i=1;i<=m;i++){ 49 scanf("%d",&cost[i]); 50 } 51 LL ans=0; 52 for(int i=0;i<n;i++){ 53 int id=0; 54 LL sma=inf; 55 for(int j=t;j<=in[i].time;j++){ 56 if(j+T<in[i].time) continue; 57 LL c=(cost[j]+(in[i].time-j)*S)*in[i].R; 58 if(sma>c){ 59 sma=c; 60 id=j; 61 } 62 } 63 if(s+T>=in[i].time){ 64 LL c=(cost[s]+(in[i].time-s)*S)*in[i].R; 65 if(sma>c){ 66 sma=c; 67 id=s; 68 } 69 } 70 ans+=sma; 71 s=id; 72 t=in[i].time; 73 } 74 printf("%I64d\n",ans); 75 } 76 return 0; 77 }
Bob’s Race http://acm.hdu.edu.cn/showproblem.php?pid=4123
用树上最长路,就是树的直径,然后求出每个点能到最远距离数组,对其rmq预处理,然后单调队列求。
1 #include<cstdio> 2 #include<cstring> 3 #include<cmath> 4 #include<algorithm> 5 #include<queue> 6 #define mt(a,b) memset(a,b,sizeof(a)) 7 using namespace std; 8 const int inf=0x3f3f3f3f; 9 const int M=50010; 10 struct G{ 11 struct E{ 12 int v,w,next; 13 }e[M<<1]; 14 int le,head[M]; 15 void init(){ 16 le=0; 17 mt(head,-1); 18 } 19 void add(int u,int v,int w){ 20 e[le].v=v; 21 e[le].w=w; 22 e[le].next=head[u]; 23 head[u]=le++; 24 } 25 }g; 26 bool vis[M]; 27 int n; 28 queue<int> q; 29 void bfs(int s,int dist[]){ 30 for(int i=1;i<=n;i++){ 31 dist[i]=inf; 32 vis[i]=false; 33 } 34 vis[s]=true; 35 dist[s]=0; 36 while(!q.empty()) q.pop(); 37 q.push(s); 38 while(!q.empty()){ 39 int u=q.front(); 40 q.pop(); 41 for(int i=g.head[u];~i;i=g.e[i].next){ 42 int v=g.e[i].v; 43 if(vis[v]) continue; 44 vis[v]=true; 45 dist[v]=dist[u]+g.e[i].w; 46 q.push(v); 47 } 48 } 49 } 50 int getfarid(int dist[]){ 51 int res,big=0; 52 for(int i=1;i<=n;i++){ 53 if(big<dist[i]){ 54 big=dist[i]; 55 res=i; 56 } 57 } 58 return res; 59 } 60 int d1[M],d2[M],a[M]; 61 class Range_Maximum_Query{///区间最值查询离线算法init_o(nlogn),query_o(1) 62 int LOG[M],dpmax[M][20],dpmin[M][20]; 63 public: 64 void init(){///使用类前调用一次即可 65 LOG[0]=-1; 66 for(int i=1;i<M;i++){ 67 LOG[i]=LOG[i>>1]+1; 68 } 69 } 70 void Make_RMQ(int n,int a[]){///传入点的个数,下标1开始 71 for(int i=1;i<=n;i++){ 72 dpmax[i][0]=dpmin[i][0]=a[i]; 73 } 74 for(int j=1;j<=LOG[n];j++){ 75 for(int i=1;i+(1<<j)-1<=n;i++){ 76 dpmax[i][j]=max(dpmax[i][j-1],dpmax[i+(1<<(j-1))][j-1]); 77 dpmin[i][j]=min(dpmin[i][j-1],dpmin[i+(1<<(j-1))][j-1]); 78 } 79 } 80 } 81 int get_RMQ(int a,int b,bool big){///传入1返回max,传入0返回min 82 int k=LOG[b-a+1]; 83 if(big) 84 return max(dpmax[a][k],dpmax[b-(1<<k)+1][k]); 85 return min(dpmin[a][k],dpmin[b-(1<<k)+1][k]); 86 } 87 }rmq; 88 int main(){ 89 int m,u,v,w; 90 rmq.init(); 91 while(~scanf("%d%d",&n,&m),n|m){ 92 g.init(); 93 for(int i=0;i<n-1;i++){ 94 scanf("%d%d%d",&u,&v,&w); 95 g.add(u,v,w); 96 g.add(v,u,w); 97 } 98 bfs(1,d1); 99 int ss=getfarid(d1); 100 bfs(ss,d2); 101 int tt=getfarid(d2); 102 bfs(tt,d1); 103 for(int i=1;i<=n;i++){ 104 a[i]=max(d1[i],d2[i]); 105 } 106 rmq.Make_RMQ(n,a); 107 while(m--){ 108 scanf("%d",&w); 109 int s=1,t=1,ans=0; 110 while(true){ 111 if(rmq.get_RMQ(s,t,1)-rmq.get_RMQ(s,t,0)<=w){ 112 ans=max(ans,t-s+1); 113 t++; 114 } 115 else{ 116 s++; 117 } 118 if(t>n) break; 119 } 120 printf("%d\n",ans); 121 } 122 } 123 return 0; 124 }