多校联合(4)
感觉这次数学题挺多的,这次的数据应该不能说水了,有的卡的确实挺厉害,但觉得有的题还是很无语,比如说那个Trouble,二分感觉不超的,就是过不了,不是WA,就是TLE,还会MLE,一个简单的hash就可以过。是不是太卡算法了。
题目:http://acm.hdu.edu.cn/showproblem.php?pid=4334
这道题真没什么好说的
View Code
1 #include <stdio.h> 2 #include <string.h> 3 #include <iostream> 4 #include <algorithm> 5 #define mod 100007 6 #define N 6 7 #define M 210 8 #define _clr(a,val) (memset(a,val,sizeof(a))) 9 10 using namespace std; 11 12 typedef long long ll; 13 ll a[N][M]; 14 ll mark[mod]; 15 bool vis[mod]; 16 int find(ll key) 17 { 18 int tem; 19 tem = key % mod; 20 if(tem < 0) tem += mod; 21 while(vis[tem] && mark[tem] != key) 22 tem = (tem + 1) % mod; 23 return tem; 24 } 25 int main() 26 { 27 int i,j,k; 28 int t,n; 29 //freopen("data.txt","r",stdin); 30 scanf("%d",&t); 31 while(t--) 32 { 33 _clr(mark,0); 34 _clr(vis,0); 35 scanf("%d",&n); 36 for(i = 0; i < 5; i++) 37 { 38 for(j = 0; j < n; j++) 39 scanf("%I64d",&a[i][j]); 40 } 41 ll ans,cnt; 42 for(i = 0; i < n; i++) 43 { 44 for(j = 0; j < n; j++) 45 { 46 ans = (a[0][i] + a[1][j]); 47 cnt = find(ans); 48 mark[cnt] = ans; 49 vis[cnt] = 1; 50 } 51 } 52 int flag = 0; 53 for(i = 0; i < n; i++) 54 { 55 for(j = 0; j < n; j++) 56 { 57 for(k = 0; k < n; k++) 58 { 59 ans = -(a[2][i] + a[3][j] + a[4][k]); 60 cnt = find(ans); 61 if(vis[cnt]) 62 { 63 flag = 1; 64 break; 65 } 66 } 67 if(flag) break; 68 } 69 if(flag) break; 70 } 71 if(flag) printf("Yes\n"); 72 else printf("No\n"); 73 } 74 return 0; 75 }
题目:http://acm.hdu.edu.cn/showproblem.php?pid=4337
题意:给一些关系,说明两个人是好朋友,然后有一个圆桌问是否可以让所有人都坐下,每个人的两旁都是自己的好朋友,如果可以就输出入座的顺序
明白了题意之后第一个反应就是dfs,可是如果是 150 * 150 的dfs怕会超掉,就没有写,觉得写了也是浪费时间,没想到dfs还真的过了,可能是当时没有注意到题目中给的 每个人至少有一半的人都是他的好朋友 这句话的作用
View Code
1 #include <stdio.h> 2 #include <string.h> 3 #include <iostream> 4 #include <algorithm> 5 #define mod 100007 6 #define N 160 7 #define M 210 8 #define _clr(a,val) (memset(a,val,sizeof(a))) 9 10 using namespace std; 11 12 int map[N][N]; 13 bool vis[N]; 14 int path[N]; 15 int sum; 16 int n; 17 int flag; 18 //int num; 19 int dfs(int x) 20 { 21 if(sum == n) 22 { 23 printf("%d",path[0]); 24 for(int i = 1; i < sum; i++) 25 printf(" %d",path[i]); 26 printf("\n"); 27 flag = 1; 28 return 1; 29 } 30 for(int i = 2; i <= n; i++) 31 if(map[x][i] && !vis[i]) 32 { 33 34 if(sum == n - 1 && !map[i][path[0]]) continue; 35 //cout<<i<<" "<<endl; 36 vis[i] = 1, path[sum] = i, sum ++; 37 if(dfs(i)) return 1; 38 vis[i] = 0, sum --; 39 } 40 return 0; 41 } 42 int main() 43 { 44 int i,m; 45 int x,y; 46 //freopen("data.txt","r",stdin); 47 while(scanf("%d%d",&n,&m) != EOF) 48 { 49 _clr(vis,0); 50 _clr(map,0); 51 _clr(path,0); 52 for(i = 0; i < m; i++) 53 { 54 scanf("%d%d",&x,&y); 55 map[x][y] = map[y][x] = 1; 56 } 57 flag = 0; 58 vis[1] = 1; 59 path[0] = 1; 60 sum = 1; 61 dfs(1); 62 if(!flag) 63 printf("no solution\n"); 64 } 65 return 0; 66 }
题目:http://acm.hdu.edu.cn/showproblem.php?pid=4336
当时看着过的人挺多的,然后我们就一直在看那个题,研究样例怎么过,可是n久也弄不出样例,最后看我们学校的队都没人试,也就放弃了,说一定是一个简单题,没那么复杂,看了解题+标程时我是觉得那个公式挺简单的,但是怎么来的,为什么是那样,就不懂了,题解里说是容斥原理,
中等偏难的概率/组合数学。设卡片的分布p=(p1,p2,...,pn),T(p)表示拿到所有卡片时买的零食数目,有。由容斥原理得,
根据这个公式就可以了,下面是标程里计算这个公式的核心代码
View Code
1 int temp = 1 << n; 2 ans = 0; 3 for(i = 1; i < temp; i++) 4 { 5 tem = num = 0; 6 for(j = 0; j < n; j++) 7 { 8 if(i & (1 << j)) 9 { 10 //cout<<"j = "<<j<<endl; 11 tem += p[j]; 12 num++; 13 } 14 } 15 if(num & 1) ans += (1 / tem); 16 else ans += (-1 / tem); 17 }