狗狗40题~ (Volume C)
A - Triangles
记忆化搜索呗。搜索以某三角形为顶的最大面积,注意边界情况。
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 dp[110][220];
16 char g[110][220];
17 int main(){
18 int n,h,cs=1;
19 while(scanf("%d",&n) && n){
20 for(int i=0;i<n;i++)scanf("%s",g[i]);
21 memset(dp,0,sizeof dp);
22
23 printf("Triangle #%d\n",cs++);
24 if(n==1){
25 printf("The largest triangle area is %d.\n\n",g[0][0]=='#'?0:1);
26 continue;
27 }
28
29 h=0;
30 for(int j=0;j<2*n-1;j++)if(g[0][j]!='#')dp[0][j]=h=1;
31 for(int i=1;i<n;i++){
32 int j;
33 for(j=0;j<2*(n-i);j+=2)if(g[i][j]!='#'){
34 int f=i-1,p=j+1;
35 while(f>=0&&g[f][p]!='#'&&g[f][p+1]!='#')f--,p+=2;
36 dp[i][j]=min(1+dp[i-1][j],i-f);
37 h=max(h,dp[i][j]);
38 }
39 }
40 if(g[n-2][1]!='#'){dp[n-2][1]=1;h=max(h,1);}
41 for(int i=n-3;i>=0;i--){
42 int j;
43 for(j=1;j<2*(n-i)-1;j+=2)if(g[i][j]!='#'){
44 if(j<2)dp[i][j]=1;
45 else{
46 int f=i+1,p=j-1;
47 while(f<n && j<2*(n-f)-1 && g[f][p]!='#' && g[f][p+1]!='#')f++;
48 dp[i][j]=min(1+dp[i+1][j-2],f-i);
49 }
50 h=max(h,dp[i][j]);
51 }
52 }
53 printf("The largest triangle area is %d.\n\n",h*h);
54 }
55 return 0;
56 }
B - Domino Effect
基本就是最短路问题,权值为正,最后要用 t=(dis[i]+dis[j]+g[i][j])/2.0 计算边上最后一个多米诺倒下的时间。
1 #include <stdio.h>
2 #include <cstring>
3 #include <cstdlib>
4 #include <algorithm>
5 #include <cmath>
6 #include <queue>
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 20000000000LL
14
15 typedef long long ll;
16 int g[505][505],n,m,vis[505];
17 ll d[505];
18 double t;int x,y;
19 void dijkstra(){
20 for(int i=2;i<=n;i++)d[i]=INF;
21 d[1]=0;
22 for(int i=0;i<n;i++){
23 int u;
24 ll tm=INF;
25 for(int j=1;j<=n;j++)if(!vis[j]&&d[j]<tm){
26 u=j;tm=d[j];
27 }
28 if(tm>=INF)break;
29 vis[u]=1;
30 for(int j=1;j<=n;j++)if(g[u][j]!=-1&&!vis[j])
31 d[j]=min(d[j],g[u][j]+d[u]);
32 }
33 for(int i=1;i<=n;i++){
34 if(t<d[i]){x=i;y=0;t=d[i];}
35 for(int j=1;j<i;j++)if(g[i][j]!=-1){
36 double temp=(g[i][j]+d[i]+d[j])/2.0;
37 if(t<temp){x=j;y=i;t=temp;}
38 }
39
40 }
41 }
42 int main(){
43 int a,b,l,cs=1;
44 while(scanf("%d%d",&n,&m) && n){
45 memset(g,-1,sizeof g);
46 memset(vis,0,sizeof vis);
47 t=0;x=1;y=0;
48 for(int i=0;i<m;i++){
49 scanf("%d%d%d",&a,&b,&l);
50 g[a][b]=g[b][a]=l;
51 }
52 dijkstra();
53 printf("System #%d\n",cs++);
54 if(!y){
55 printf("The last domino falls after %.1lf seconds, at key domino %d.\n\n",t,x);
56 }else{
57 printf("The last domino falls after %.1lf seconds, between key dominoes %d and %d.\n\n",t,x,y);
58 }
59 }
60 return 0;
61 }
C - Pendulum
代码还比较简短,注意转的时候不能高于x轴
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 const double pi=acos(-1); 17 struct point{ 18 int x,y; 19 point() {} 20 point(int x,int y): x(x),y(y) {} 21 point operator + (const point a){return point(x+a.x,y+a.y);} 22 point operator - (const point a){return point(x-a.x,y-a.y);} 23 }p[505]; 24 int n; 25 int dcmp(double x){ 26 if(x>eps)return 1; 27 else if(x<-eps)return -1; 28 return 0; 29 } 30 double dist(point c){ 31 return sqrt((double)c.x*c.x+(double)c.y*c.y); 32 } 33 double ans; 34 void swing(int o,double l,double ang){ 35 double a0=2*pi,dm=0.0; 36 int next=-1; 37 double amax=2*pi; 38 if(dcmp(p[o].y-l)<0)amax=pi+asin(p[o].y/l)-ang; 39 for(int i=1;i<n;i++)if(i!=o){ 40 double d=dist(p[i]-p[o]); 41 if(dcmp(d-l)>=0)continue; 42 double a=atan2(p[i].y-p[o].y,p[i].x-p[o].x)-ang; 43 while(a<0)a+=2*pi; 44 if(dcmp(a-amax)>=0)continue; 45 if(dcmp(a-a0)<0||(dcmp(a-a0)==0&&d>dm)){ 46 dm=d,a0=a; 47 next=i; 48 } 49 } 50 if(next!=-1){ 51 ans+=a0*l; 52 double a=a0+ang; 53 if(a>=2*pi)a-=2*pi; 54 swing(next,l-dm,a); 55 } 56 else if(dcmp(p[o].y-l)<0)ans+=amax*l; 57 else ans=pi*l; 58 } 59 60 int main(){ 61 int cs=1; 62 double r; 63 while(scanf("%d%lf",&n,&r) && dcmp(r)){ 64 n++; 65 p[0]=point(0,0); 66 for(int i=1;i<n;i++){ 67 scanf("%d%d",&p[i].x,&p[i].y); 68 p[i].x=-p[i].x,p[i].y=-p[i].y; 69 } 70 ans=0.0; 71 swing(0,r,0.0); 72 printf("Pendulum #%d\n",cs++); 73 printf("Length of periodic orbit = %.2lf\n\n",ans*2); 74 } 75 return 0; 76 }
D - The New Villa
这种题应该一看数据规模就知道是bfs可以水过的。
1 #include <stdio.h>
2 #include <cstdlib>
3 #include <cstring>
4 #include <algorithm>
5
6 #define STA 30000
7 int q[STA],d[STA],fa[STA],vis[STA],ans[STA];
8 int to[15][15],sw[15][15];
9 int n,k,s;
10 int bfs(int st){
11 int l,r;
12 l=r=0;
13 int now=(1<<st)*10+st-1;
14 q[r++]=now;
15 fa[now]=-1;
16 while(l<r){
17 now=q[l++];
18 int room=now%10+1,sta=now/10;
19 if(room==n&&sta==(1<<n))return 1;
20 int next;
21 for(int i=1;i<=n;i++)if(!vis[now-room+i] && to[room][i] && sta&(1<<i)){
22 next=now-room+i;
23 vis[next]=1;
24 d[next]=d[now]+1;
25 fa[next]=now;
26 q[r++]=next;
27 }
28 for(int i=1;i<=n;i++)if(i!=room && sw[room][i]){
29 if(!(sta&(1<<i)) && !vis[(sta|(1<<i))*10+room-1]){
30 next=(sta|(1<<i))*10+room-1;
31 vis[next]=1;
32 d[next]=d[now]+1;
33 fa[next]=now;
34 q[r++]=next;
35 }
36 else if(sta&(1<<i) && !vis[(sta^(1<<i))*10+room-1]){
37 next=(sta^(1<<i))*10+room-1;
38 vis[next]=1;
39 d[next]=d[now]+1;
40 fa[next]=now;
41 q[r++]=next;
42 }
43 }
44 }
45 return 0;
46
47 }
48 int main(){
49 //freopen("input.in","r",stdin);freopen("output.out","w",stdout);
50 int cs=1;
51 while(scanf("%d%d%d",&n,&k,&s) &&n){
52 int x,y;
53 memset(to,0,sizeof to);
54 memset(sw,0,sizeof sw);
55 memset(vis,0,sizeof vis);
56 memset(d,0,sizeof d);
57 while(k--){
58 scanf("%d%d",&x,&y);
59 to[x][y]=to[y][x]=1;
60 }
61 while(s--){
62 scanf("%d%d",&x,&y);
63 sw[x][y]=1;
64 }
65 printf("Villa #%d\n",cs++);
66 if(bfs(1)){
67 int u=(1<<n)*10+n-1,dis;
68 printf("The problem can be solved in %d steps:\n",dis=d[u]);
69 for(int i=0;i<dis;i++){
70 ans[i]=u;
71 u=fa[u];
72 }
73 int lastroom=1,sta0=1<<1,room,sta;
74 for(int i=dis-1;i>=0;i--){
75 room=ans[i]%10+1;sta=ans[i]/10;
76 if(room!=lastroom)printf("- Move to room %d.\n",room);
77 else{
78 for(int j=1;j<=n;j++)if((sta0&(1<<j))!=(sta&(1<<j))){
79 if(sta0&(1<<j))printf("- Switch off light in room %d.\n",j);
80 else printf("- Switch on light in room %d.\n",j);
81 break;
82 }
83 }
84 lastroom=room;sta0=sta;
85 }
86 printf("\n");
87
88 }else printf("The problem cannot be solved.\n\n");
89
90 }
91 return 0;
92 }
E - Parallelepiped Walk
巧妙地转化成坐标旋转的问题,有几个简化代码的技巧
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 14 typedef long long ll; 15 int xx,yy,zz; 16 ll ans; 17 ll dist(int x,int y){ 18 return (ll)x*x+(ll)y*y; 19 } 20 void go(int dx,int dy,int x,int y,int z,int x1,int x2,int y1,int y2,int h){ 21 if(z==0){ 22 ans=min(ans,dist(x-xx,y-yy)); 23 return; 24 } 25 if(dx>=0&&dx<2)go(dx+1,dy,x2+z,y,x2-x,x2,x2+h,y1,y2,x2-x1); 26 if(dx<=0&&dx>-2)go(dx-1,dy,x1-z,y,x-x1,x1-h,x1,y1,y2,x2-x1); 27 if(dy>=0&&dy<2)go(dx,dy+1,x,y2+z,y2-y,x1,x2,y2,y2+h,y2-y1); 28 if(dy<=0&&dy>-2)go(dx,dy-1,x,y1-z,y-y1,x1,x2,y1-h,y1,y2-y1); 29 } 30 int main(){ 31 int x0,y0,z0,x,y,z; 32 while(~scanf("%d%d%d%d%d%d%d%d%d",&x0,&y0,&z0,&xx,&yy,&zz,&x,&y,&z)){ 33 if(xx==0||xx==x0){ 34 swap(xx,zz); 35 swap(x0,z0); 36 swap(x,z); 37 } 38 else if(yy==0||yy==y0){ 39 swap(yy,zz); 40 swap(y0,z0); 41 swap(y,z); 42 } 43 if(zz==z0){ 44 zz=z0-zz; 45 z=z0-z; 46 } 47 ans=INF; 48 go(0,0,x,y,z,0,x0,0,y0,z0); 49 printf("%lld\n",ans); 50 } 51 return 0; 52 }
F - Decoding Morse Sequences
我的做法是把所有单词的Morse码编进Trie树,在词尾标记访问次数,然后记忆化搜索。
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 ch[1000010][3],sz;
16 char morse[26][10]
17 ={".-","-...","-.-.","-..",".","..-.","--.","....","..",".---","-.-",".-..",
18 "--","-.","---",".--.","--.-",".-.","...","-","..-","...-",".--","-..-","-.--","--.."};
19 char s[10100],word[25],mod[100];
20 ll dp[10100];
21 int t[1000010];
22
23 void insert(char *s){
24 char *p=s;
25 int u=0;
26 for(;*p!='\0';p++){
27 int temp;
28 if(*p=='.')temp=1;
29 else temp=2;
30 if(ch[u][temp]==-1)ch[u][temp]=++sz;
31 u=ch[u][temp];
32 }
33 if(ch[u][0]==-1)ch[u][0]=++sz;
34 u=ch[u][0];
35 t[u]++;
36 }
37 ll dfs(int now){
38 if(dp[now]>=0)return dp[now];
39 ll &ans=dp[now];
40 ans=0;
41 int u=0,flag=1;
42 for(int i=now;s[i];i++){
43 int temp;
44 if(s[i]=='.')temp=1;
45 else temp=2;
46 if(ch[u][temp]==-1)return ans;
47 u=ch[u][temp];
48 if(ch[u][0]!=-1)ans+=t[ch[u][0]]*dfs(i+1);
49 }
50 return ans;
51 }
52 int main(){
53 //freopen("r.in","r",stdin);freopen("r.out","w",stdout);
54 int T;
55 scanf("%d",&T);
56 while(T--){
57 scanf("%s",s);
58 int m;
59 scanf("%d",&m);
60 memset(ch,-1,sizeof ch);
61 memset(t,0,sizeof t);
62 sz=0;
63 for(int i=0;i<m;i++){
64 mod[0]='\0';
65 scanf("%s",word);
66 for(int j=0;word[j];j++)
67 strcat(mod,morse[word[j]-'A']);
68 insert(mod);
69 }
70 memset(dp,-1,sizeof dp);
71 dp[strlen(s)]=1;
72 dfs(0);
73 printf("%lld\n",dp[0]);
74 }
75 return 0;
76 }
G - Fill the Cisterns!
二分答案,精度0.0005.
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 2000000
13 #define eps 5e-4
14
15 typedef long long ll;
16
17 struct cistern{
18 double b,h,s;
19 }c[50010];
20 double v,hmax,hmin;
21 int n;
22
23 int cmp(cistern a,cistern b){return a.b<b.b;}
24
25 int cal(double dh){
26 double vx=0;
27 for(int i=0;i<n&&c[i].b<dh;i++){
28 double t=min(c[i].b+c[i].h,dh);
29 vx+=(t-c[i].b)*c[i].s;
30 }
31 if(vx<v)return -1;
32 if(vx>v)return 1;
33 return 0;
34 }
35 double search(double low,double hi){
36 double mid;
37 while(hi-low>eps){
38 mid=(hi+low)/2.0;
39 if(cal(mid)>=0)hi=mid;
40 else low=mid;
41 }
42 return hi;
43 }
44 int main(){
45 //freopen("r.in","r",stdin);freopen("r.out","w",stdout);
46 int t;
47 scanf("%d",&t);
48 while(t--){
49 scanf("%d",&n);
50 double w,h,vmax;
51 hmax=0;hmin=INF;
52 vmax=0;
53 for(int i=0;i<n;i++){
54 scanf("%lf%lf%lf%lf",&c[i].b,&c[i].h,&w,&h);
55 c[i].s=w*h;
56 hmax=max(hmax,c[i].h+c[i].b);
57 hmin=min(hmin,c[i].b);
58 vmax+=c[i].s*c[i].h;
59 }
60 scanf("%lf",&v);
61 if(vmax<v){
62 printf("OVERFLOW\n");
63 continue;
64 }
65
66 sort(c,c+n,cmp);
67 double dh=search(hmin,hmax);
68 printf("%.2lf\n",dh);
69
70 }
71 return 0;
72 }
H - Horizontally Visible Segments
线段树染色问题……每次询问一次更新一次,中间hash判重然后加边,最后暴力搜索得到 Triangle 个数。
有个细节是x,y在[0,8000],0<=n<=8000,建立的图应该是稀疏图,用vector存,所以一定要判重的!
1 #include <stdio.h>
2 #include <cstdlib>
3 #include <cstring>
4 #include <algorithm>
5 #include <vector>
6
7 #define rson o<<1|1
8 #define lson o<<1
9 #define H 16000
10 #define MOD 1403641
11
12 using namespace std;
13
14 vector <int> g[8010];
15 int col[16000<<2],y1,y2;
16
17 struct segment{
18 int y1,y2,x;
19 }seg[8010];
20 struct Hash{
21 int va;
22 Hash *next;
23 Hash(){va=-1;next=NULL;}
24 }hash[MOD];
25 void init(){
26 for(int i=0;i<MOD;i++){hash[i].va=-1;hash[i].next=NULL;}
27 }
28 int exist(int u,int v){
29 int x=u*10000+v;
30 if(hash[x%MOD].va==-1){hash[x%MOD].va=x;return 0;}
31 else{
32 Hash *u=&hash[x%MOD];
33 while(u->next!=NULL){
34 if(u->va==x)return 1;
35 u=u->next;
36 }
37 if(u->va==x)return 1;
38 u->next=new Hash;
39 u->next->va=x;u->next->next=NULL;
40 return 0;
41 }
42 }
43 int cmp(struct segment a,struct segment b){return a.x<b.x;}
44 void pushdown(int o,int l,int r){
45 if(col[o]!=-1){
46 col[rson]=col[lson]=col[o];
47 }
48 }
49 void upd(int o,int l,int r,int u){
50 if(y1<=l&&y2>=r){
51 col[o]=u;
52 }else if(y2>=l&&y1<=r){
53 int mid=(l+r)>>1;
54 pushdown(o,l,r);
55 col[o]=-1;
56 if(y1<=mid)upd(lson,l,mid,u);
57 if(y2>mid)upd(rson,mid+1,r,u);
58 }
59 }
60 void que(int o,int l,int r,int v){
61 int mid=(l+r)/2;
62 if(y1<=l&&y2>=r){
63 if(col[o]==-1){
64 que(lson,l,mid,v);
65 que(rson,mid+1,r,v);
66 }else if(col[o]&&!exist(v,col[o])){
67 g[v].push_back(col[o]);
68 }
69 }else if(y2>=l&&y1<=r){
70 pushdown(o,l,r);
71 if(y1<=mid)que(lson,l,mid,v);
72 if(y2>mid)que(rson,mid+1,r,v);
73 }
74 }
75 int main(){
76 int T,n;
77 scanf("%d",&T);
78 while(T--){
79 scanf("%d",&n);
80 for(int i=1;i<=n;i++)scanf("%d%d%d",&seg[i].y1,&seg[i].y2,&seg[i].x);
81 sort(seg+1,seg+n+1,cmp);
82
83 for(int i=1;i<=n;i++)g[i].clear();
84 memset(col,0,sizeof col);
85 init();
86 for(int i=1;i<=n;i++){
87 y1=seg[i].y1*2;y2=seg[i].y2*2;
88 if(i>1)que(1,0,H,i);
89 upd(1,0,H,i);
90 }
91 int cnt=0;
92 for(int i=3;i<=n;i++)if(g[i].size()>1)
93 for(int j=0;j<g[i].size();j++){
94 int u=g[i][j];
95 for(int k=0;k<g[u].size();k++)
96 for(int q=0;q<g[i].size();q++)if(g[i][q]==g[u][k])cnt++;
97 }
98
99 printf("%d\n",cnt);
100 }
101 return 0;
102 }
I - 2D Nim
按照每个点向四个方向走的最大步数来判断,哈希查找
1 #include <stdio.h> 2 #include <cstring> 3 #include <cstdlib> 4 #include <algorithm> 5 #include <cmath> 6 using namespace std; 7 #define lson o<<1 8 #define rson o<<1|1 9 #define max(a,b) (a)>(b)?(a):(b) 10 #define min(a,b) (a)<(b)?(a):(b) 11 #define INF 2000000000 12 #define M 240 13 14 typedef long long ll; 15 int g[120][120]; 16 int n,m; 17 struct hash_table{ 18 int v[4]; 19 bool vis; 20 hash_table* next; 21 hash_table(){vis=0;next=NULL;} 22 void init(){ 23 vis=0; 24 next=NULL; 25 } 26 void insert(int *t){ 27 if(!vis){ 28 for(int i=0;i<4;i++)v[i]=t[i]; 29 vis=1; 30 } 31 else{ 32 hash_table *u=new hash_table; 33 u->next=next; 34 next=u; 35 u->vis=1; 36 for(int i=0;i<4;i++)u->v[i]=t[i]; 37 } 38 } 39 int search(int *t){ 40 if(vis){ 41 bool flag=1; 42 for(int i=0;i<4;i++)if(v[i]!=t[i])flag=0; 43 if(flag){vis=0;return 1;} 44 } 45 hash_table* now=next; 46 while(now!=NULL){ 47 if(now->vis){ 48 bool flag=1; 49 for(int i=0;i<4;i++)if(now->v[i]!=t[i])flag=0; 50 if(flag){now->vis=0;return 1;} 51 } 52 now=now->next; 53 } 54 return 0; 55 } 56 }hash[M]; 57 int main(){ 58 // freopen("r.in","r",stdin);freopen("r.out","w",stdout); 59 int t; 60 scanf("%d",&t); 61 while(t--){ 62 int k; 63 scanf("%d%d%d",&n,&m,&k); 64 memset(g,0,sizeof g); 65 for(int i=0;i<M;i++)hash[i].init(); 66 int x,y; 67 for(int i=0;i<k;i++){ 68 scanf("%d%d",&x,&y); 69 g[x][y]=1; 70 } 71 int tm[4]; 72 for(int i=0;i<n;i++) 73 for(int j=0;j<m;j++)if(g[i][j]){ 74 int tot=0; 75 memset(tm,0,sizeof tm); 76 for(int x=i-1;x>=0&&g[x][j];x--)tm[0]++,tot++; 77 for(int x=i+1;x<n&&g[x][j];x++)tm[1]++,tot++; 78 for(int y=j-1;y>=0&&g[i][y];y--)tm[2]++,tot++; 79 for(int y=j+1;y<m&&g[i][y];y++)tm[3]++,tot++; 80 sort(tm,tm+4); 81 hash[tot].insert(tm); 82 } 83 memset(g,0,sizeof g); 84 for(int i=0;i<k;i++){ 85 scanf("%d%d",&x,&y); 86 g[x][y]=1; 87 } 88 bool flag=1; 89 for(int i=0;i<n;i++) 90 for(int j=0;j<m;j++)if(g[i][j]){ 91 int tot=0; 92 memset(tm,0,sizeof tm); 93 for(int x=i-1;x>=0&&g[x][j];x--)tm[0]++,tot++; 94 for(int x=i+1;x<n&&g[x][j];x++)tm[1]++,tot++; 95 for(int y=j-1;y>=0&&g[i][y];y--)tm[2]++,tot++; 96 for(int y=j+1;y<m&&g[i][y];y++)tm[3]++,tot++; 97 sort(tm,tm+4); 98 if(!hash[tot].search(tm)){flag=0;break;} 99 } 100 101 if(flag)printf("YES\n"); 102 else printf("NO\n"); 103 } 104 return 0; 105 }
J - (Your)((Term)((Project)))
细节题了,递归做最保险。
1.skip空格。
2.加号(或无符号默认为加号)后面对应括号去掉。
3.重复的空格去掉。
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 #define SKIP(p) while(*p==' ')++p;
14
15 typedef long long ll;
16 char s[300],q[300];
17 int res;
18 void solve(char *s,char *q){
19 char *p;
20 int sgn=1;
21 for(p=s;p<=q;p++){
22 if(*p=='+')sgn=1;
23 else if(*p=='-')sgn=-1;
24 else if(*p=='('){
25 char *t;
26 int cnt=1;
27 for(t=p+1;t<=q;t++){
28 if(*t=='(')cnt++;
29 else if(*t==')')cnt--;
30 if(!cnt)break;
31 }
32 if(sgn>0)*p=*t=' ';
33 if(t-p>2)solve(p+1,t-1);
34 }
35 }
36 }
37 void deal(char *p,int n){
38 for(int i=0;i<n;i++)if(p[i]<='Z'&&p[i]>='A'){
39 int l=i-1,r=i+1;
40 while(l>=0&&r<n){
41 if(p[l]!='('||p[r]!=')')break;
42 p[l]=p[r]=' ';
43 l--;r++;
44 }
45 }
46 solve(p,p+n-1);
47 }
48 int main(){
49 //freopen("r.in","r",stdin);freopen("r.out","w",stdout);
50 int t;
51 scanf("%d",&t);
52 gets(s);
53 while(t--){
54 gets(s);
55 char *p=s;
56 res=0;
57 for(;*p!='\0';p++){
58 SKIP(p);
59 q[res++]=*p;
60 }
61 deal(q,res);
62 for(int i=0;i<res;i++)if(q[i]!=' ')
63 printf("%c",q[i]);
64 printf("\n");
65 }
66 return 0;
67 }