SDUT_基本算法解题报告

1001:由于每种药品的体积是相同的,所以可以按浓度排一下序,然后从小达到一直累加到不满足条件为止。主要需要使用eps判精度,在加题前测试的时候我的代码就因为精度WA了一次。

View Code
 1 #include <iostream>
2 #include <cstdio>
3 #include <cstring>
4 #include <algorithm>
5 using namespace std;
6
7 const int N = 105;
8 const double eps = 1e-6;
9
10 int C, n, v;
11 double w, p[N];
12
13 int cmp(double x){
14 if(x > eps) return 1;
15 else if(x < -eps) return -1;
16 else return 0;
17 }
18
19 int main()
20 {
21 int i = 0;
22 scanf("%d", &C);
23 while(C--){
24 double tot = 0;
25 scanf("%d%d%lf", &n, &v, &w);
26 w = w*v/100.0;
27 for(i = 0; i < n; i++){
28 scanf("%lf", p+i);
29 p[i] = p[i]*v/100.0;
30 }
31 sort(p, p+n);
32 for(i = 0; i < n; i++){
33 if(cmp(tot+p[i]-w*(i+1)) <= 0)
34 tot += p[i];
35 else break;
36 }
37 double ans = 0.0;
38 if(i != 0) ans = tot/(i*v);
39 printf("%d %.2f\n", i*v, ans);
40 }
41 return 0;
42 }


1002:很裸的快速幂,就是求a^b mod 10。会了discuss给出的链接内容就肯定木有问题啦。

View Code
 1 #include <iostream>
2 #include <cstdio>
3 #include <cstring>
4 using namespace std;
5
6 typedef long long llg;
7
8 const int N = 10;
9
10 llg pow(llg a, llg b){
11 llg tmp = a%N, ans = 1;
12 while(b){
13 if(b & 1) ans = ans * tmp % N;
14 b >>= 1;
15 tmp = tmp*tmp % N;
16 }
17 return ans;
18 }
19
20 int main()
21 {
22 llg a, b;
23 while(scanf("%I64d%I64d", &a, &b) != EOF){
24 printf("%I64d\n", pow(a, b));
25 }
26 return 0;
27 }

 

1003:简单递推,令f[n][k]表示整数n的分解出的最大数字为k时的方案总数,则f[n][k] = Sum{i<=k | f[n-j][i]}。最终的结果为Sum{1<=i<=n | f[n][i]}。

View Code
 1 #include <iostream>
2 #include <cstdio>
3 #include <cstring>
4 using namespace std;
5
6 typedef long long llg;
7
8 const int N = 121;
9
10 int f[N][N];
11
12 int main()
13 {
14 int n;
15 memset(f, 0, sizeof(f));
16 f[0][0] = 1;
17 for(int i = 1; i < N; i++){
18 for(int j = 1; j <= i; j++){
19 f[i][j] = 0;
20 for(int k = 0; k <= j; k++)
21 f[i][j] += f[i-j][k];
22 }
23 }
24 while(scanf("%d", &n) != EOF){
25 llg ans = 0;
26 for(int i = 1; i <= n; i++) ans += f[n][i];
27 printf("%I64d\n", ans);
28 }
29 return 0;
30 }

 

1004:首先二分最小差值,limit = (l+r) >> 1,然后判定在limit限定范围内是否存在一条满足条件的通路。但是如何判断是否存在一条通路呢?如果可以确定通路中的最小边权low就好了,这样的话可以利用bfs,只要满足low+limit>=w[a,b]那么就可以从a到达b。分析题目不难发现,给出的边的数目是很有限的,可以直接枚举所有可行边权分别作为最小值,利用均摊分析可以发现时间复杂度是很小的。

View Code
 1 #include <iostream>
2 #include <cstdio>
3 #include <cstring>
4 #include <vector>
5 #include <set>
6 using namespace std;
7
8 typedef long long llg;
9
10 const int N = 205;
11
12 set <int> hash;
13
14 int n, m, q;
15 int tot, h[N], w[N*10], nxt[N*10], v[N*10];
16 int queue[N];
17 bool visit[N];
18
19 void add(int a, int b, int c){
20 v[tot] = b;
21 w[tot] = c;
22 nxt[tot] = h[a];
23 h[a] = tot++;
24 }
25
26 bool bfs(int limit, int s, int t){
27 set <int>::iterator it;
28 int head, tail, tu, tv, low;
29 for(it = hash.begin(); it != hash.end(); it++){
30 head = tail = 0;
31 low = *it;
32 queue[0] = s;
33 memset(visit, false, sizeof(visit));
34 visit[s] = true;
35 while(head <= tail){
36 tu = queue[head++];
37 for(int p = h[tu]; p != -1; p = nxt[p]){
38 tv = v[p];
39 if(!visit[tv] && w[p]>=low && low+limit>=w[p]){
40 visit[tv] = true;
41 queue[++tail] = tv;
42 }
43 }
44 if(visit[t]) return true;
45 }
46 }
47 return false;
48 }
49
50 void solve(int s, int t){
51 int l=0, r=1000000, mid, ans = -1;
52 while(l <= r){
53 mid = (l+r) >> 1;
54 if(bfs(mid, s, t)){
55 ans = mid;
56 r = mid-1;
57 }
58 else l = mid+1;
59 }
60 printf("%d\n", ans);
61 }
62
63 int main()
64 {
65 int a, b, c;
66 while(scanf("%d%d", &n, &m) != EOF){
67 hash.clear();
68 memset(h, -1, sizeof(h));
69 tot = 0;
70 for(int i = 0; i < m; i++){
71 scanf("%d%d%d", &a, &b, &c);
72 hash.insert(c);
73 add(a, b, c);
74 add(b, a, c);
75 }
76 scanf("%d", &q);
77 for(int i = 0; i < q; i++){
78 scanf("%d%d", &a, &b);
79 solve(a, b);
80 }
81 }
82 return 0;
83 }






posted on 2011-11-22 21:50  Moon_1st  阅读(282)  评论(0编辑  收藏  举报

导航