H - Sorting Slides
应该是个二分匹配的模板题的,但我还不会写 = =
其实数据规模很小,就用贪心的方法就水过了(没加vis判冲突wa了几发,从此开始艰难的没有1A 的生活)
1 #include <stdio.h> 2 #include <cstring> 3 #include <cstdlib> 4 #include <algorithm> 5 #include <cmath> 6 7 using namespace std; 8 #define lson o<<1 9 #define rson o<<1|1 10 #define max(a,b) (a)>(b)?(a):(b) 11 #define min(a,b) (a)<(b)?(a):(b) 12 #define INF 200000000 13 typedef long long ll; 14 struct slide{ 15 int x1,x2,y1,y2; 16 }rec[50]; 17 int g[100][100],d[100],ans[50],vis[100]; 18 int main(){ 19 //freopen("r.in","r",stdin);freopen("r.out","w",stdout); 20 int n,cs=1; 21 while(scanf("%d",&n) && n){ 22 for(int i=0;i<n;i++)scanf("%d%d%d%d",&rec[i].x1,&rec[i].x2,&rec[i].y1,&rec[i].y2); 23 int x,y; 24 memset(d,0,sizeof d); 25 memset(g,0,sizeof g); 26 memset(vis,0,sizeof vis); 27 memset(ans,-1,sizeof ans); 28 for(int i=0;i<n;i++){ 29 scanf("%d%d",&x,&y); 30 for(int j=0;j<n;j++)if(x<rec[j].x2&&x>rec[j].x1&&y<rec[j].y2&&y>rec[j].y1){ 31 g[i][j+n]=1;d[i]++; 32 d[j+n]++; 33 } 34 } 35 int flag=1; 36 while(flag){ 37 int i,j,i0,j0; 38 flag=0; 39 for(i=0;i<n;i++)if(!vis[i]&&d[i]==1) 40 {flag=1;break;} 41 if(flag){ 42 for(j=n;j<2*n;j++)if(!vis[j]&&g[i][j])break; 43 i0=i,j0=j; 44 ans[j0-n]=i0; 45 vis[i0]=vis[j0]=1; 46 g[i0][j0]=0;d[i0]--;d[j0]--; 47 for(i=0;i<n;i++)if(g[i][j0])d[i]--,g[i][j0]=0; 48 continue; 49 } 50 for(j=n;j<2*n;j++)if(!vis[j]&&d[j]==1) 51 {flag=1;break;} 52 if(flag){ 53 for(i=0;i<n;i++)if(!vis[i]&&g[i][j])break; 54 i0=i;j0=j; 55 ans[j0-n]=i0; 56 vis[i0]=vis[j0]=1; 57 g[i0][j0]=0;d[i0]--;d[j0]--; 58 for(j=n;j<2*n;j++)if(g[i0][j])d[j]--,g[i0][j]=0; 59 continue; 60 } 61 } 62 int cnt=0; 63 printf("Heap %d\n",cs++); 64 for(int i=0;i<n;i++)if(ans[i]>=0) 65 {if(cnt)printf(" ");printf("(%c,%d)",'A'+i,ans[i]+1);cnt++;} 66 if(!cnt)printf("none"); 67 printf("\n\n"); 68 } 69 return 0; 70 }
A - Triangle Encapsulation
水题,暴搜の
1 #include <stdio.h> 2 #include <cstring> 3 #include <cstdlib> 4 #include <algorithm> 5 #include <cmath> 6 7 using namespace std; 8 #define lson o<<1 9 #define rson o<<1|1 10 #define max(a,b) (a)>(b)?(a):(b) 11 #define min(a,b) (a)<(b)?(a):(b) 12 #define INF 200000000 13 14 typedef long long ll; 15 struct point { 16 int x,y; 17 struct point operator -(const struct point b){ 18 struct point c; 19 c.x=x-b.x;c.y=y-b.y; 20 return c; 21 } 22 }p[5]; 23 int cmp(struct point a,struct point b){ 24 if(a.y-b.y)return a.y>b.y; 25 return a.x<b.x; 26 } 27 int g[20][20]; 28 int cross(struct point a,struct point b){ 29 return a.x*b.y-a.y*b.x; 30 } 31 int main(){ 32 //freopen("r.in","r",stdin);freopen("r.out","w",stdout); 33 printf("Program 4 by team X\n"); 34 while(scanf("%d%d",&p[0].x,&p[0].y)!=EOF){ 35 for(int i=1;i<3;i++)scanf("%d%d",&p[i].x,&p[i].y); 36 struct point pi; 37 memset(g,0,sizeof g); 38 int xmin=18,ymin=18,ymax=0,xx[20]={0}; 39 for(pi.x=-9;pi.x<=9;pi.x++) 40 for(pi.y=-9;pi.y<=9;pi.y++){ 41 int c1=0,c2=0; 42 for(int i=0;i<3;i++){ 43 if(cross(pi-p[i],pi-p[(i+1)%3])<0)c1++; 44 if(cross(pi-p[i],pi-p[(i+1)%3])>0)c2++; 45 } 46 if(c1==3||c2==3){ 47 g[pi.x+9][pi.y+9]=1; 48 xmin=min(xmin,pi.x+9); 49 xx[pi.y+9]=max(xx[pi.y+9],pi.x+9); 50 ymin=min(ymin,pi.y+9); 51 ymax=max(ymax,pi.y+9); 52 } 53 } 54 int x,y; 55 for(y=ymax;y>=ymin;y--){ 56 for(x=xmin;x<=xx[y];x++){ 57 if(x>xmin)printf(" "); 58 if(g[x][y])printf("(%2d,%3d)",x-9,y-9); 59 else printf(" "); 60 } 61 printf("\n"); 62 } 63 printf("\n"); 64 } 65 printf("End of program 4 by team X\n"); 66 return 0; 67 }
G - Reflections
几何题。解析算错很多次,其实就是算交点和关于直线对称。用向量点积和叉积不容易错。
1 #include <stdio.h> 2 #include <cstring> 3 #include <cstdlib> 4 #include <algorithm> 5 #include <cmath> 6 #include <utility> 7 8 using namespace std; 9 #define lson o<<1 10 #define rson o<<1|1 11 #define max(a,b) (a)>(b)?(a):(b) 12 #define min(a,b) (a)<(b)?(a):(b) 13 #define INF 200000000 14 #define eps 1e-6 15 16 typedef long long ll; 17 int n,ans[30],cur; 18 struct point{ 19 double x,y; 20 }; 21 struct circle{ 22 double x,y,r; 23 }cir[30]; 24 struct line{ 25 double x0,y0,dx,dy; 26 }ori; 27 int sgn(double x){ 28 if(x>eps)return 1; 29 if(x<-eps)return -1; 30 return 0; 31 } 32 pair <double,int> inter(struct line now){ 33 double a,b,c,del,t1,t2,t=-1; 34 int use=-1; 35 for(int i=1;i<=n;i++){ 36 a=now.dx*now.dx+now.dy*now.dy; 37 b=now.dx*(now.x0-cir[i].x)+now.dy*(now.y0-cir[i].y); 38 c=(now.x0-cir[i].x)*(now.x0-cir[i].x)+(now.y0-cir[i].y)*(now.y0-cir[i].y)-cir[i].r*cir[i].r; 39 del=b*b-a*c; 40 if(sgn(del)<=0)continue; 41 t1=(-b-sqrt(del))/a; 42 t2=(-b+sqrt(del))/a; 43 if(sgn(t1)>0){ 44 if(t==-1||t>t1)t=t1,use=i; 45 } 46 else if(sgn(t2)>0){ 47 if(t==-1||t>t2)t=t2,use=i; 48 } 49 } 50 return make_pair(t,use); 51 } 52 void work(struct line now){ 53 if(cur>10)return; 54 double t=inter(now).first; 55 if(t<=0)return; 56 int i0=ans[cur++]=inter(now).second; 57 58 /* 求对称射线 */ 59 double x,y,xx,yy; 60 x=now.x0+t*now.dx; 61 y=now.y0+t*now.dy; 62 if(sgn(now.dy*(x-cir[i0].x)-now.dx*(y-cir[i0].y))==0){ 63 now.x0=x;now.y0=y; 64 now.dx=-now.dx;now.dy=-now.dy; 65 work(now); 66 return; 67 } 68 xx=-((x-cir[i0].x)*now.dx+(y-cir[i0].y)*now.dy)/cir[i0].r; 69 yy=((x-cir[i0].x)*now.dy-(y-cir[i0].y)*now.dx)/cir[i0].r; 70 now.x0=x;now.y0=y; 71 now.dx=(xx*(x-cir[i0].x)-yy*(y-cir[i0].y))/cir[i0].r; 72 now.dy=(xx*(y-cir[i0].y)+yy*(x-cir[i0].x))/cir[i0].r; 73 work(now); 74 } 75 76 int main(){ 77 //freopen("r.in","r",stdin);freopen("r.out","w",stdout); 78 int cs=1; 79 while(scanf("%d",&n) && n){ 80 int i; 81 for(i=1;i<=n;i++)scanf("%lf%lf%lf",&cir[i].x,&cir[i].y,&cir[i].r); 82 scanf("%lf%lf%lf%lf",&ori.x0,&ori.y0,&ori.dx,&ori.dy); 83 cur=0; 84 work(ori); 85 printf("Scene %d\n",cs++); 86 for(i=0;i<cur&&i<10;i++)printf("%d ",ans[i]); 87 if(cur>10)printf("...\n\n"); 88 else printf("inf\n\n"); 89 } 90 return 0; 91 }
C - Robbery
一开始有点不敢写,想了一下其实每个时间点只和前后两个点有关,所以正着跑一次再倒着check一遍就确定了。
1 #include <stdio.h> 2 #include <cstring> 3 #include <cstdlib> 4 #include <algorithm> 5 #include <cmath> 6 7 using namespace std; 8 #define lson o<<1 9 #define rson o<<1|1 10 #define max(a,b) (a)>(b)?(a):(b) 11 #define min(a,b) (a)<(b)?(a):(b) 12 #define INF 200000000 13 14 typedef long long ll; 15 int w,h,T,n; 16 int g[105][105][105]; 17 struct message{ 18 int t,l,u,r,d; 19 }mes[105]; 20 struct answer{ 21 int t,x,y; 22 }ans[105]; 23 int cmp(struct message a,struct message b){ 24 return a.t<b.t; 25 } 26 void direct(){ 27 int k=0; 28 memset(g,-1,sizeof g); 29 memset(g[1],0,sizeof g[1]); 30 for(int t=1;t<=T;t++){ 31 //to expand reachable area. 32 if(t>1) 33 for(int i=1;i<=h;i++) 34 for(int j=1;j<=w;j++)if(!g[t-1][i][j]){ 35 g[t][i][j]=0; 36 if(i>1)g[t][i-1][j]=0; 37 if(j>1)g[t][i][j-1]=0; 38 if(i<h)g[t][i+1][j]=0; 39 if(j<w)g[t][i][j+1]=0; 40 } 41 //to receive the messge. 42 for(;k<n&&mes[k].t==t;k++){ 43 for(int i=mes[k].u;i<=mes[k].d;i++) 44 for(int j=mes[k].l;j<=mes[k].r;j++) 45 g[t][i][j]=-1; 46 } 47 48 } 49 } 50 void inverse(){ 51 int k=n-1; 52 for(int t=T-1;t>0;t--){ 53 for(int i=1;i<=h;i++) 54 for(int j=1;j<=w;j++)if(!g[t][i][j]){ 55 if(!g[t+1][i][j])continue; 56 if(i>1&&!g[t+1][i-1][j])continue; 57 if(j>1&&!g[t+1][i][j-1])continue; 58 if(i<h&&!g[t+1][i+1][j])continue; 59 if(j<w&&!g[t+1][i][j+1])continue; 60 g[t][i][j]=-1; 61 } 62 } 63 } 64 int main(){ 65 //freopen("r.in","r",stdin);freopen("r.out","w",stdout); 66 int cs=1; 67 while(scanf("%d%d%d",&w,&h,&T) && w){ 68 scanf("%d",&n); 69 for(int i=0;i<n;i++) 70 scanf("%d%d%d%d%d",&mes[i].t,&mes[i].l,&mes[i].u,&mes[i].r,&mes[i].d); 71 sort(mes,mes+n,cmp); 72 direct(); 73 inverse(); 74 printf("Robbery #%d:\n",cs++); 75 int res=0,flag=1; 76 for(int t=1;t<=T;t++){ 77 int cn=0,x,y; 78 for(int i=1;i<=h;i++) 79 for(int j=1;j<=w;j++)if(!g[t][i][j])x=i,y=j,cn++; 80 if(!cn){flag=0;break;} 81 if(cn==1)ans[res].t=t,ans[res].x=x,ans[res++].y=y; 82 } 83 if(!flag)printf("The robber has escaped.\n\n"); 84 else{ 85 if(!res)printf("Nothing known.\n\n"); 86 else{ 87 for(int i=0;i<res;i++)printf("Time step %d: The robber has been at %d,%d.\n",ans[i].t,ans[i].y,ans[i].x); 88 printf("\n"); 89 } 90 } 91 } 92 return 0; 93 }
E - Triangle War
状压dp,极大极小算法。
另外有个坑点是每次把能取的三角形位置都取完不一定是最优策略。。
1 #include <stdio.h> 2 #include <cstring> 3 #include <cstdlib> 4 #include <algorithm> 5 #include <cmath> 6 7 using namespace std; 8 #define lson o<<1 9 #define rson o<<1|1 10 #define max(a,b) (a)>(b)?(a):(b) 11 #define min(a,b) (a)<(b)?(a):(b) 12 #define INF 200000000 13 14 typedef long long ll; 15 int edge[15][15],tri[10]={7,152,52,352,34304,3200,71680,12544,155648}; 16 int dp[1<<18]; 17 int check(int sta){ 18 int ans=0; 19 for(int i=0;i<9;i++)if((sta&tri[i])==tri[i])ans++; 20 return ans; 21 } 22 void dfs(){ 23 int s=(1<<18)-1; 24 dp[s]=0; 25 for(s=s-1;s>=0;s--){ 26 int ori=check(s),cn,maxdp=-10; 27 for(int i=0;i<18;i++)if(!((1<<i)&s)){ 28 int to=(1<<i)|s; 29 int temp=check(to)-ori; 30 if(temp)temp+=dp[to]; 31 else temp-=dp[to]; 32 maxdp=max(maxdp,temp); 33 } 34 dp[s]=maxdp; 35 } 36 } 37 int main(){ 38 //freopen("r.in","r",stdin);freopen("r.out","w",stdout); 39 int t,gm,G; 40 edge[1][2]=1;edge[1][3]=1<<1; 41 edge[2][3]=1<<2;edge[2][4]=1<<3;edge[2][5]=1<<4; 42 edge[3][5]=1<<5;edge[3][6]=1<<6; 43 edge[4][5]=1<<7;edge[4][7]=1<<9;edge[4][8]=1<<10; 44 edge[5][6]=1<<8;edge[5][8]=1<<11;edge[5][9]=1<<12; 45 edge[6][9]=1<<13;edge[6][10]=1<<14; 46 edge[7][8]=1<<15;edge[8][9]=1<<16;edge[9][10]=1<<17; 47 dfs(); 48 scanf("%d",&t); 49 while(t--){ 50 scanf("%d",&G); 51 for(gm=1;gm<=G;gm++){ 52 int m,sta=0,u,v,turn=0; 53 int a[2]={0}; 54 scanf("%d",&m); 55 for(int i=1;i<=m;i++){ 56 scanf("%d%d",&u,&v); 57 int ori=check(sta); 58 sta+=edge[u][v]; 59 ori=check(sta)-ori; 60 a[turn]+=ori; 61 if(!ori)turn=!turn; 62 } 63 printf("Game %d: ",gm); 64 a[turn]+=dp[sta]; 65 if(a[0]>a[1])printf("A wins.\n"); 66 else printf("B wins.\n"); 67 } 68 if(t)printf("\n"); 69 } 70 return 0; 71 }
B - Symbolic Derivation
可以用string数组代替栈来做模拟
1 #include <stdio.h> 2 #include <cstring> 3 #include <iostream> 4 #include <cstdlib> 5 #include <stack> 6 #include <cctype> 7 #include <string> 8 9 using namespace std; 10 #define lson o<<1 11 #define rson o<<1|1 12 #define max(a,b) (a)>(b)?(a):(b) 13 #define min(a,b) (a)<(b)?(a):(b) 14 #define INF 2000000000 15 16 typedef long long ll; 17 char sgn[500]; 18 string dev[500]; 19 string oii[500]; 20 string add(string a,string b,char op){ 21 if(op=='+'){ 22 string temp=a; 23 if(b[0]!='+'&&b[0]!='-')temp+="+"; 24 temp+=b; 25 return temp; 26 }else{ 27 string temp=a; 28 if(b[0]=='+')b.replace(0,1,"-"); 29 else if(b[0]=='-')b.replace(0,1,"+"); 30 else temp+="-"; 31 temp+=b; 32 return temp; 33 } 34 } 35 void multi(int &po,int &pd){ 36 string o2=oii[--po]; 37 string o1=oii[--po]; 38 string d2=dev[--pd]; 39 string d1=dev[--pd]; 40 string t1="("; 41 t1+=d1;t1+="*";t1+=o2; 42 string t2; 43 t2+=o1;t2+="*";t2+=d2;t2+=")"; 44 dev[pd++]=add(t1,t2,'+'); 45 o1+="*";o1+=o2; 46 oii[po++]=o1; 47 } 48 void divi(int &po,int &pd){ 49 string o2=oii[--po]; 50 string o1=oii[--po]; 51 string d2=dev[--pd]; 52 string d1=dev[--pd]; 53 string t1="("; 54 t1+=d1;t1+="*";t1+=o2; 55 string t2; 56 t2+=o1;t2+="*";t2+=d2;t2+=")/"; 57 string temp=add(t1,t2,'-'); 58 temp+=o2;temp+="^2"; 59 dev[pd++]=temp; 60 o1+="/";o1+=o2; 61 oii[po++]=o1; 62 } 63 void loge(int &po,int &pd){ 64 string o=oii[--po]; 65 string d=dev[--pd]; 66 string temp="ln"; 67 temp+=o; 68 oii[po++]=temp; 69 temp=""; 70 temp+=d;temp+="/"; 71 temp+=o; 72 dev[pd++]=temp; 73 } 74 string derivation(char *s,int n){ 75 int sg=0,dv=0,oi=0; 76 bool beg=0; 77 for(int i=0;i<n;i++){ 78 if(!beg&&(s[i]=='+'||s[i]=='-')){ 79 char *p=s+i; 80 if(s[++i]!='x'){ 81 while(isdigit(s[i])||s[i]=='.')i++; 82 string temp=string(p,s+i); 83 oii[oi++]=temp; 84 dev[dv++]="0"; 85 } 86 else{ 87 string temp=s[i]=='-'?"-x":"+x"; 88 oii[oi++]=temp; 89 temp=s[i]=='-'?"-1":"+1"; 90 dev[dv++]=temp; 91 ++i; 92 } 93 } 94 beg=1; 95 if(isdigit(s[i])){ 96 char *p=s+i; 97 while(isdigit(s[i])||s[i]=='.')i++; 98 string temp=string(p,s+i); 99 oii[oi++]=temp; 100 dev[dv++]="0"; 101 } 102 if(s[i]=='x'){ 103 oii[oi++]="x"; 104 dev[dv++]="1"; 105 ++i; 106 } 107 if(s[i]=='l'){ 108 i++; 109 sgn[sg++]='l'; 110 } 111 else if(s[i]=='*'||s[i]=='/'){ 112 if(sg&&(sgn[sg-1]=='*'||sgn[sg-1]=='/')){ 113 char u=sgn[--sg]; 114 if(u=='*'){ 115 multi(oi,dv); 116 } 117 if(u=='/'){ 118 divi(oi,dv); 119 } 120 } 121 sgn[sg++]=s[i]; 122 } 123 else if(s[i]=='+'||s[i]=='-'){ 124 if(sg&&sgn[sg-1]!='('){ 125 char u=sgn[--sg]; 126 if(u=='*'){ 127 multi(oi,dv); 128 } 129 if(u=='/'){ 130 divi(oi,dv); 131 } 132 if(u=='+'||u=='-'){ 133 string o1=oii[--oi]; 134 oii[oi-1]=add(oii[oi-1],o1,u); 135 string d1=dev[--dv]; 136 dev[dv-1]=add(dev[dv-1],d1,u); 137 } 138 } 139 sgn[sg++]=s[i]; 140 } 141 else if(s[i]=='(')sgn[sg++]=s[i],beg=0; 142 else if(s[i]==')'){ 143 char u; 144 while(sg&&sgn[sg-1]!='('){ 145 u=sgn[--sg]; 146 if(u=='*'){ 147 multi(oi,dv); 148 } 149 if(u=='/'){ 150 divi(oi,dv); 151 } 152 if(u=='+'||u=='-'){ 153 string o1=oii[--oi]; 154 oii[oi-1]=add(oii[oi-1],o1,u); 155 string d1=dev[--dv]; 156 dev[dv-1]=add(dev[dv-1],d1,u); 157 } 158 } 159 //add brackets. 160 if(u!='*'&&u!='/'){ 161 string temp="("; 162 temp+=dev[--dv]; 163 temp+=")"; 164 dev[dv++]=temp; 165 temp="("; 166 temp+=oii[--oi]; 167 temp+=")"; 168 oii[oi++]=temp; 169 } 170 sg--; 171 if(sgn[sg-1]=='l'){ 172 loge(oi,dv); 173 sg--; 174 } 175 } 176 } 177 char u; 178 while(sg){ 179 u=sgn[--sg]; 180 if(u=='*'){ 181 multi(oi,dv); 182 } 183 if(u=='/'){ 184 divi(oi,dv); 185 } 186 if(u=='+'||u=='-'){ 187 string o1=oii[--oi]; 188 oii[oi-1]=add(oii[oi-1],o1,u); 189 string d1=dev[--dv]; 190 dev[dv-1]=add(dev[dv-1],d1,u); 191 } 192 } 193 return dev[dv-1]; 194 } 195 196 char buf[200]; 197 int main(){ 198 //freopen("r.in","r",stdin);freopen("r.out","w",stdout); 199 while(~scanf("%s",buf)){ 200 string ans=derivation(buf,strlen(buf)); 201 cout << ans << endl; 202 } 203 return 0; 204 }
F - Metal Cutting
半平面交,中间思考人生把排序写挫了好久才看出来。。
1 #include <stdio.h> 2 #include <cstring> 3 #include <cstdlib> 4 #include <algorithm> 5 #include <cmath> 6 7 using namespace std; 8 #define lson o<<1 9 #define rson o<<1|1 10 #define max(a,b) (a)>(b)?(a):(b) 11 #define min(a,b) (a)<(b)?(a):(b) 12 #define INF 2000000000 13 #define eps 1e-6 14 15 typedef long long ll; 16 int dcmp(double x){ 17 if(x>eps)return 1; 18 if(x<-eps)return -1; 19 return 0; 20 } 21 struct point{ 22 double x,y; 23 point(){} 24 point(double x,double y):x(x),y(y){} 25 point operator - (point a){return point(x-a.x,y-a.y);} 26 point operator + (point a){return point(x+a.x,y+a.y);} 27 point operator * (double c){return point(x*c,y*c);} 28 }po[20],fin[20]; 29 struct line{ 30 point p,v; 31 double ang; 32 line(){} 33 line(point p,point v):p(p),v(v){ang=atan2(v.y,v.x);} 34 }li[20]; 35 double cross(point a,point b){ 36 return a.x*b.y-a.y*b.x; 37 } 38 double dot(point a,point b){ 39 return a.x*b.x+a.y*b.y; 40 } 41 double length(point a){ 42 return sqrt(dot(a,a)); 43 } 44 bool Onleft(line L,point p){ 45 return cross(L.v,p-L.p)>0; 46 } 47 bool cmp_l(line a,line b){ 48 return a.ang<b.ang; 49 } 50 bool cmp(point a,point b){ 51 if(dcmp(a.x-b.x))return a.x<b.x; 52 return a.y<b.y; 53 } 54 point GetIntersection(line a,line b){ 55 point u=a.p-b.p; 56 double t=cross(b.v,u)/cross(a.v,b.v); 57 return a.p+a.v*t; 58 } 59 point deq[20]; 60 line q[20]; 61 int HalfPlane(line *L,int n,point *poly){ 62 sort(L,L+n,cmp_l); 63 64 int l,r; 65 q[l=r=0]=L[0]; 66 for(int i=1;i<n;i++){ 67 while(l<r && !Onleft(L[i],deq[r-1]))r--; 68 while(l<r && !Onleft(L[i],deq[l]))l++; 69 q[++r]=L[i]; 70 if(!dcmp(q[r].ang-q[r-1].ang)){ 71 r--; 72 if(Onleft(q[r],L[i].p))q[r]=L[i]; 73 } 74 if(l<r)deq[r-1]=GetIntersection(q[r],q[r-1]); 75 } 76 while(l<r && !Onleft(q[l],deq[r-1]))r--; 77 if(r>l+1)deq[r]=GetIntersection(q[r],q[l]); 78 else return 0; 79 80 int m=0; 81 for(int i=l;i<=r;i++)poly[m++]=deq[i]; 82 return m; 83 } 84 int perm[20],vis[20],h,w; 85 double ans; 86 void dfs(int now,int n){ 87 if(now==n){ 88 li[0]=line(point(0,0),point(1,0)); 89 li[1]=line(point(w,0),point(0,1)); 90 li[2]=line(point(w,h),point(-1,0)); 91 li[3]=line(point(0,h),point(0,-1)); 92 int m=HalfPlane(li,4,po); 93 double temp=0; 94 point tp[5]; 95 for(int i=0;i<n;i++){ 96 line now=line(fin[perm[i]],fin[perm[i]]-fin[(perm[i]+1)%n]); 97 int res=0; 98 for(int j=0;j<m;j++){ 99 if(!dcmp(cross(now.v,po[(j+1)%m]-po[j])))continue; 100 tp[res]=GetIntersection(now,line(po[j],po[(j+1)%m]-po[j])); 101 if(dcmp(dot(tp[res]-po[j],tp[res]-po[(j+1)%m]))<=0)res++; 102 } 103 sort(tp,tp+res,cmp); 104 if(res>1)temp+=length(tp[res-1]-tp[0]); 105 else continue; 106 li[i+4]=now; 107 m=HalfPlane(li,i+5,po); 108 } 109 ans=min(ans,temp); 110 return; 111 } 112 for(int i=0;i<n;i++)if(!vis[i]){ 113 vis[i]=1; 114 perm[now]=i; 115 dfs(now+1,n); 116 vis[i]=0; 117 } 118 } 119 int main(){ 120 //freopen("r.in","r",stdin);freopen("r.out","w",stdout); 121 int t; 122 scanf("%d",&t); 123 while(t--){ 124 int vt; 125 scanf("%d%d",&w,&h); 126 scanf("%d",&vt); 127 for(int i=0;i<vt;i++)scanf("%lf%lf",&fin[i].x,&fin[i].y); 128 ans=INF; 129 memset(vis,0,sizeof vis); 130 dfs(0,vt); 131 printf("Minimum total length = %.3lf\n",ans); 132 if(t)printf("\n"); 133 } 134 return 0; 135 }
D - Dreisam Equations
就是暴力加表达式计算。(一直SegmentationFault不明所以,发现是代表符号的值取的不好会和数值冲突=_=)
1 #include <stdio.h> 2 #include <cstring> 3 #include <cstdlib> 4 #include <algorithm> 5 #include <cmath> 6 #include <stack> 7 8 using namespace std; 9 #define lson o<<1 10 #define rson o<<1|1 11 #define max(a,b) (a)>(b)?(a):(b) 12 #define min(a,b) (a)<(b)?(a):(b) 13 #define INF 200000000 14 #define zuokuo 200000000 15 #define youkuo 200000001 16 #define kong 200000009 17 #define jia -200000000 18 #define jian -200000001 19 #define cheng -200000002 20 21 typedef long long ll; 22 char eq[1000]; 23 int q[1000],res; 24 int lf; 25 stack <int> a; 26 stack <int> s; 27 int solve(int cur){ 28 if(cur==res){ 29 while(!a.empty())a.pop(); 30 while(!s.empty())s.pop(); 31 for(int i=0;i<res;i++){ 32 if(q[i]>-200000000&&q[i]<200000000){ 33 if(s.empty()||s.top()==zuokuo)a.push(q[i]); 34 else{ 35 int u=a.top();a.pop(); 36 if(s.top()==jia)a.push(u+q[i]); 37 if(s.top()==jian)a.push(u-q[i]); 38 if(s.top()==cheng)a.push(u*q[i]); 39 s.pop(); 40 } 41 } 42 else if(q[i]==youkuo){ 43 if(s.empty()||s.top()!=zuokuo)return 0; 44 s.pop(); 45 if(s.empty()||s.top()==zuokuo)continue; 46 int u=a.top();a.pop(); 47 int v=a.top();a.pop(); 48 if(s.top()==jia)a.push(v+u); 49 if(s.top()==jian)a.push(v-u); 50 if(s.top()==cheng)a.push(v*u); 51 s.pop(); 52 } 53 else s.push(q[i]); 54 } 55 if(a.top()==lf)return 1; 56 else return 0; 57 } 58 if(q[cur]!=kong)return solve(cur+1); 59 for(int i=cheng;i<=jia;i++){ 60 q[cur]=i; 61 if(solve(cur+1))return 1; 62 q[cur]=kong; 63 } 64 return 0; 65 } 66 int main(){ 67 int cs=1; 68 while(gets(eq) && eq[0]!='0'){ 69 sscanf(eq,"%d",&lf); 70 res=0; 71 int i; 72 for(i=0;eq[i]!='=';i++); 73 for(i++;eq[i]!='\0';i++){ 74 for(;eq[i]==' ';i++); 75 if(eq[i]=='('){q[res++]=zuokuo;continue;} 76 if(eq[i]==')'){q[res-1]=youkuo;q[res++]=kong;continue;} 77 int num=0; 78 while(eq[i]>='0'&&eq[i]<='9'){ 79 num=num*10+eq[i]-'0'; 80 i++; 81 } 82 q[res++]=num; 83 q[res++]=kong; 84 i=i-1; 85 } 86 res=res-1; 87 88 printf("Equation #%d:\n",cs++); 89 if(solve(0)==0)printf("Impossible\n\n"); 90 else{ 91 printf("%d=",lf); 92 for(int i=0;i<res;i++){ 93 if(q[i]==zuokuo)printf("("); 94 else if(q[i]==youkuo)printf(")"); 95 else if(q[i]==jia)printf("+"); 96 else if(q[i]==jian)printf("-"); 97 else if(q[i]==cheng)printf("*"); 98 else printf("%d",q[i]); 99 } 100 printf("\n\n"); 101 } 102 103 } 104 return 0; 105 }