做题地址:http://acm.hdu.edu.cn/diy/contest_login.php?cid=16600
Problem A :HDU1172
//枚举 #include <stdio.h> int check1(int num1, int num2, int t) { int a[4], b[4]; int c[4]; int i, j; for(i=0; i<4; i++) { a[i] = num1%10; num1 /= 10; b[i] = num2%10; num2 /= 10; c[i] = 0; } int m = 0; for(i=0; i<4; i++) { for(j=0; j<4; j++) if(c[j]==0 && a[i]==b[j]) { m ++; c[j] = 1; break; } } if(m == t) return 1; else return 0; } int check2(int num1, int num2, int t) { int a[4], b[4]; int i; int m = 0; for(i=0; i<4; i++) { a[i] = num1%10; num1 /= 10; b[i] = num2%10; num2 /= 10; if(a[i] == b[i]) m++; } if(m == t) return 1; else return 0; } int main() { int a[101], b[101], c[101]; int cnt, res; int n,i,j; while(scanf("%d",&n),n) //输入N,且N不为0 { //存入数组 for(i=0; i<n; i++) scanf("%d%d%d", &a[i], &b[i], &c[i]); cnt = 0; //遍历所有4位数,每一个拿去试 for(i=1000; i<=9999; i++) { //试每种猜测的情况 for(j=0; j<n; j++) { if(check1(i, a[j], b[j]) == 0) break; if(check2(i, a[j], c[j]) == 0) break; } if(j >= n) { cnt ++; res = i; } if(cnt >= 2) break; } if(cnt==0 || cnt>=2) puts("Not sure"); else printf("%d\n", res); } return 0; }
Problem B: HDU1051
题义:给定若干(1<= n <=5000)组二维坐标点,凡是满足 "x1<= x2 && y1<= y2"的话那么我们承认这两个坐标是属于同一个集合中。题目要我们求出这些坐标点最少能表示成几个集合。
For example, if you have five sticks whose pairs of length and weight are (4,9), (5,2), (2,1), (3,5), and (1,4), then the minimum setup time should be 2 minutes since there is a sequence of pairs (1,4), (3,5), (4,9), (2,1), (5,2).
先将所有的点的信息保存起来,然后选取 x 或者 y 作为对象进行排序,排序中注意如果两个点的 x相同,那么这时候要保持 y有序。这样做的目的是使得所有集合线性的呈现出来,可以理解为经过这样一次排序后,能够每次从前到后找到一个包含点满足题义且最多的点集。不会出现正确分离出来的集合在该排列中有元素是逆序的。
代码如下:
#include <stdio.h> #include <stdlib.h> #include <string.h> int T; struct E { int len, wi; } e[5010]; char hash[5010]; int cmp(const void *a, const void *b) { if(((struct E *)a)-> len!= ((struct E *)b)-> len) { return ((struct E *)a)-> len- ((struct E *)b)-> len; } else { return ((struct E *)a)-> wi- ((struct E *)b)-> wi; } } int find(int N) { int i; for(i=0; i< N; ++i) { if(!hash[i]) { return i; } } return -1; } int ok(int i, int baselen, int basewi) { if(e[i].wi>= basewi) { return 1; } else { return 0; } } int main() { scanf("%d", &T); while(T--) { memset(hash, 0, sizeof(hash)); int N, time= 0, i; scanf("%d", &N); for(i= 0; i< N; ++i) { scanf("%d %d", &e[i].len, &e[i].wi); } qsort(e, N, sizeof(e[0]), cmp); int sta; while(1) { sta = find(N); if(sta== -1) { break; } int baselen= e[sta].len, basewi= e[sta].wi; for(i= sta; i< N; ++i) { if(!hash[i]&& ok(i, baselen, basewi)) { hash[i]= 1; baselen= e[i].len; basewi= e[i].wi; } } ++time; } printf("%d\n", time); } return 0; }
Problem C: HDU 1005
//递推 找规律 #include <stdio.h> #include <string.h> int main() { int a, b, n; int s[50]; while(scanf("%d%d%d", &a, &b, &n), a || b || n) { int i; s[0] = s[1] = 1; for(i = 2; i<50;i++) { s[i] = (a*s[i-1]+b*s[i-2]) % 7; if(s[i] ==1 && s[i-1] == 1) { break; } } n = n%(i-1); if(n == 0) printf("%d\n", s[i-2]); else printf("%d\n", s[n-1]); } return 0; }