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 }
View Code

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
",ans);
75     }
76     return 0;
77 }
View Code

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
",ans);
121         }
122     }
123     return 0;
124 }
View Code

end

原文地址:https://www.cnblogs.com/gaolzzxin/p/3975530.html