BestCoder 1st Anniversary ($)

Hdu  5310  Souvenir

题目描述:

  水题,三种方案求最小值即可。

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <iostream>
 4 #include <algorithm>
 5 using namespace std;
 6 int main ()
 7 {
 8     int n, m, q, p, t;
 9     scanf ("%d", &t);
10     while (t --)
11     {
12         scanf ("%d %d %d %d", &n, &m, &p, &q);
13         int num1, num2, ans;
14         num1 = p * n;
15         num2 = n / m * q;
16         ans = n % m * p;
17         if (ans > q)
18             num2 += q;
19         else
20             num2 += ans;
21         printf ("%d
", min(num1, num2));
22     }
23     return 0;
24 }
View Code

Hdu 5311 Hidden String

题目描述:

  在一个长串里面找到三个不交叉的子串,这三个不交叉的子串按照顺序相连与"anniversary"相等,问能不能求出来三个这样的子串?

解题思路:

  暴力水题,"anniversary"有11个字母,在10个间隔里面枚举出两个间隔,然后在长串中按照顺序找这三个子串。

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <iostream>
 4 #include <algorithm>
 5 using namespace std;
 6 const int maxn = 110;
 7 char str[maxn], S[20] = "anniversary";
 8 bool solve ();
 9 int main ()
10 {
11     int t;
12     scanf ("%d", &t);
13     while (t --)
14     {
15         scanf ("%s", str);
16         if (solve())
17             printf("YES
");
18         else
19             printf ("NO
");
20     }
21     return 0;
22 }
23 bool solve ()
24 {
25     int len = strlen(str), a[10];
26     a[0] = 0;
27     a[3] = 11;
28     for (a[1]=1; a[1]<10; a[1]++)
29         for (a[2]=a[1]+1; a[2]<11; a[2]++)
30         {
31             int num = 0;
32             for (int k=0; k<len;)
33             {
34                 int i = a[num], j = a[num+1];
35                 while (S[i] != str[k] && k<len)
36                     k ++;
37                 while (S[i]==str[k] && i<j && k<len)
38                 {
39                     i ++;
40                     k ++;
41                 }
42                 if (i == j)
43                     num ++;
44             }
45             if (num == 3)
46                 return true;
47         }
48     return false;
49 }
View Code

Hdu 5312 Sequence

题目描述:

  有一组数为3*n*(n-1),(n>=1)。给出一个m,问至少需要这组数里面的几个相加才能等于m。

解题思路:

  这个题目成功把Bestcoder变身成为Hackcoder,出题人题面上给出的两个实例推导,以及Simple Input都在有意无意的想表明这个题目就是贪心,贪心也可以过掉,真是出题良心啊!!!!题目做不出来,也可以让你Hack拿高分。真是感动到死。

  只要了解了三角形数,这个也是水题。任何一个自然数都可以用三个三角形数相加得来,在枚举由两个数组合而来的时候,可以用经典的相向搜索把复杂度变为O(n),O(n*n)的复杂度TLE估计稳稳的

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <iostream>
 4 #include <algorithm>
 5 using namespace std;
 6 const int maxn = 18500;
 7 int a[maxn];
 8 void init ()
 9 {
10     for (int i=0; i<maxn; i++)
11         a[i] = 3*i*(i-1)+1;
12 }
13 int solve (int n)
14 {
15     int ans = n % 6;
16     if (ans == 1)
17     {
18         for (int i=0; i<maxn; i++)
19             if (a[i] == n)
20                 return 1;
21         return 7;
22     }
23     if (ans == 2)
24     {
25         int j = maxn - 1;
26         for (int i=1; i<=j; i++)
27         {
28             while (a[i]+a[j]>n)
29                 j --;
30             if (a[i] + a[j] == n)
31                 return 2;
32         }
33         return 8;
34     }
35     return (n - 1) % 6 + 1;
36 }
37 int main ()
38 {
39     int t;
40     scanf ("%d", &t);
41     init ();
42     while (t --)
43     {
44         int n;
45         scanf ("%d", &n);
46         printf ("%d
", solve(n));
47     }
48     return 0;
49 }
View Code

Hdu  5313  Bipartite Graph

题目描述:

  给出一个无环,无重边的二分图,问最多加几条边可以使所给二分图变成一个完全二分图。

解题思路:

  求出连通块,并对连通块中的节点进行标记,然后把每个连通块中不同的节点分别放在x,y集合中,使得||x| - |y||最小即可,最终答案就是x*y-m。

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <iostream>
 4 #include <algorithm>
 5 using namespace std;
 6 const int maxn = 10010;
 7 struct node
 8 {
 9     int to, next;
10 } edge[maxn*20];
11 int head[maxn], vis[maxn], used[maxn];
12 int x, y, tot, n, m;
13 void init ()
14 {
15     tot = x = y = 0;
16     memset (used, 0, sizeof(used));
17     memset (head, -1, sizeof(head));
18     memset (vis, -1, sizeof(vis));
19 }
20 void Add (int from, int to)
21 {
22     edge[tot].to = to;
23     edge[tot].next = head[from];
24     head[from] = tot ++;
25 }
26 void dfs (int u, int c, int &a, int &b)
27 {
28     b ++;
29     if (c)
30         a ++;
31     vis[u] = c;
32     for (int i=head[u]; i!=-1; i=edge[i].next)
33     {
34         int v = edge[i].to;
35         if (vis[v] == -1)
36             dfs(v, c^1, a, b);
37     }
38 }
39 int main ()
40 {
41     int t;
42     scanf ("%d", &t);
43     while (t --)
44     {
45         init ();
46         scanf ("%d %d", &n, &m);
47         for (int i=0; i<m; i++)
48         {
49             int u, v;
50             scanf ("%d %d", &u, &v);
51             used[u] = used[v] = 1;
52             Add (u, v);
53             Add (v, u);
54         }
55         int num = 0;
56         for (int i=1; i<=n; i++)
57         {
58             int a = 0;
59             int b = 0;
60             if (!used[i])
61             {
62                 num ++;
63                 continue;
64             }
65             if (vis[i] == -1)
66                 dfs (i, 0, a, b);
67             b -= a;
68             x += max (a, b);
69             y += min (a, b);
70             if (x > y)
71                 swap (x, y);
72         }
73         if (num >= y - x)
74         {
75             num -= y - x;
76             x = y;
77         }
78         x += num / 2;
79         y += num - num / 2;
80         printf ("%d
", x*y-m);
81     }
82     return 0;
83 }
View Code
本文为博主原创文章,未经博主允许不得转载。
原文地址:https://www.cnblogs.com/alihenaixiao/p/4677563.html