链接:第二次小练
这次是我们这组出的题目~我出了一道......B-Prison rearrangement,感觉有点复杂~不过其实题目想通了还是很简单的......
@荆红浅醉出的是A、C、D,@从此不再出的是E——一道很尼玛的二分......题目难懂啊~~~
这一次很凑巧,大家出的题目的题面都是英文而且....比较长......不过这都是巧合.....= =
B.Prison rearrangement POJ 1636
题意:就是两个监狱换犯人,他们想换一半,但是发现两个监狱的有部分犯人不能放在一个监狱里,否则会有危险,就问在尽可能换一半犯人前提下,最多能换多少犯人~(就觉得这个想换犯人的长官是没事找抽型……= =)
方法简析:先是用DFS搜索两个监狱,看换犯人的话有多少是要同时换的(即不能在一个监狱)。【注:DFS要搜索两遍,一遍是从A监狱,一遍是从B监狱,这是要保证都不能在同意监狱的被搜索到~】再找出最多要换的人数~
代码:
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 using namespace std; 5 6 bool vis[2][205],map[205][205],dp[205][205]; //vis[0][i]代表的是A监狱i号犯人;vis[1][i]代表的是B号监狱i号犯人~~~;map记录的是两个监狱里的犯人是否有关联 7 int m,r,asize,bsize; //asize,bsize分别代表A、B监狱要换的人数 8 9 void DFS(int p,int id) 10 { 11 vis[p][id]=1; 12 int i; 13 if(p==0) 14 { 15 asize++; 16 for(i=1;i<=m;i++) 17 if(!vis[1][i] && map[id][i]) //若未标记,则搜索与该点不能呆在一起的犯人~ 18 DFS(1,i); 19 } 20 else 21 { 22 bsize++; 23 for(i=1;i<=m;i++) 24 if(!vis[0][i] && map[i][id]) //若未被标记,则搜索与该点不能呆在一起的犯人~~ 25 DFS(0,i); 26 } 27 } 28 29 void bag() 30 { 31 dp[0][0]=true; 32 for(int i=m/2;i>=asize;i--) 33 for(int j=m/2;j>=bsize;j--) 34 if(dp[i][j] || dp[i-asize][j-bsize]) dp[i][j]=true; //对搜索到的两个监狱的人数进行标记~ 35 } 36 37 int main() 38 { 39 int t,a,b,i; 40 scanf("%d",&t); 41 while(t--) 42 { 43 memset(vis,0,sizeof(vis)); 44 memset(map,0,sizeof(map)); 45 memset(dp,0,sizeof(dp)); 46 scanf("%d%d",&m,&r); 47 for(i=0;i<r;i++) 48 { 49 scanf("%d%d",&a,&b); 50 map[a][b]=1; 51 } 52 for(i=1;i<=m;i++) 53 if(!vis[0][i]) 54 { 55 asize=0; 56 bsize=0; 57 DFS(0,i); 58 bag(); 59 } 60 for(i=1;i<=m;i++) 61 if(!vis[1][i]) 62 { 63 asize=0; 64 bsize=0; 65 DFS(1,i); 66 bag(); 67 } 68 for(i=m/2;i>=0;i--) 69 if(dp[i][i]) /*若在前面搜索中出现A、B两个监狱搜索的人数一样多,并人数小于m/2,即该人数是符合要求的,那么就输出该人数~从后面开始搜是为了保证得到的是最大值*/ 70 { 71 printf("%d\n",i); 72 break; 73 } 74 } 75 return 0; 76 }
//memory:228KB time:79ms
水到爆的题目..............没什么好讲的~
代码:
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 using namespace std; 6 7 class Shuchu 8 { 9 public: 10 double sum; 11 int id; 12 }a[1000]; 13 14 bool comp(Shuchu q,Shuchu w) 15 { 16 if(q.sum==w.sum) 17 return q.id<w.id; 18 return q.sum>w.sum; 19 } 20 bool cmp(Shuchu q,Shuchu w) 21 { 22 return q.id>w.id; 23 } 24 25 double b[1000][1000]; 26 27 int main() 28 { 29 int p,e,ne,i,j; 30 31 while(scanf("%d%d%d",&p,&e,&ne)!=EOF) 32 { 33 for(i=0;i<p;i++) 34 for(j=0;j<e;j++) 35 scanf("%lf",&b[i][j]); 36 memset(a,0,sizeof(a)); 37 for(i=0;i<e;i++) 38 for(j=0;j<p;j++) 39 { 40 a[i].sum+=b[j][i]; 41 a[i].id=i+1; 42 } 43 sort(a,a+e,comp); 44 sort(a,a+ne,cmp); 45 for(i=0;i<ne-1;i++) 46 printf("%d ",a[i].id); 47 printf("%d\n",a[ne-1].id); 48 } 49 return 0; 50 }
//memory:720KB time:62ms
与前不久做的俄罗斯套娃的题目十分相似~WA了几次是没有考虑到,俄罗斯套娃中相同的娃娃不能套在一起,但是这道题是可以的~但我就完全按照俄罗斯套娃做了,结果.......= =内牛满面啊.....
代码:
1 #include <iostream> 2 #include <cstring> 3 #include <cstdio> 4 #include <algorithm> 5 using namespace std; 6 7 class Point 8 { 9 public: 10 int x,y,id; 11 }a[5050]; 12 13 bool comp(Point q,Point w) 14 { 15 if(q.x==w.x) 16 return q.y>w.y; 17 return q.x>w.x; 18 } 19 20 int main() 21 { 22 int t,n,i,j,number,minn; 23 scanf("%d",&t); 24 while(t--) 25 { 26 memset(a,0,sizeof(a)); 27 scanf("%d",&n); 28 for(i=0;i<n;i++) 29 scanf("%d%d",&a[i].x,&a[i].y); 30 sort(a,a+n,comp); 31 number=0; 32 minn=0; 33 for(i=0;i<n;i++) 34 if(a[i].id==0) 35 { 36 a[i].id=1; 37 number++; 38 minn=a[i].y; 39 for(j=i+1;j<n;j++) 40 { 41 if(a[j].id==0 && a[j].y<=minn ) 42 { 43 a[j].id=1; 44 minn=a[j].y; 45 } 46 } 47 } 48 printf("%d\n",number); 49 } 50 return 0; 51 }
//memory:288KB time:15ms
//神二分啊~刚开始听说是二分,自己还小庆幸了一下.......结果.......尼玛题目都看不懂啊.......= =