您的位置:首页 > 理论基础 > 数据结构算法

CDU集训代码:基础算法和数据结构

2012-08-11 21:28 507 查看
做题地址: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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: