CodeForces Round #278 (Div.2) (待续)

A

这么简单的题直接贴代码好了。

 1 #include <cstdio>
 2 #include <cmath>
 3 using namespace std;
 4
 5 bool islucky(int a)
 6 {
 7     a = abs(a);
 8     while(a)
 9     {
10         if(a % 10 == 8) return true;
11         a /= 10;
12     }
13     return false;
14 }
15
16 int main(void)
17 {
18     int a, b = 1;
19     scanf("%d", &a);
20     while(!islucky(a + b)) b++;
21     printf("%d\n", b);
22
23     return 0;
24 }

代码君

B

题意:

有4个从小到大排列的正整数,x1 x2 x3 x4 ,他们满足下面三个数相等:

现在丢了4-n的数,只剩下其中的n个数(0≤n≤4)

问能否找到4-n个正整数,使得这四个数重新满足上面的条件。

分析:

这道题思路很简单,就是比较繁琐,看到有人写了100多甚至200行代码,所以我还是觉得有必要把我的思路详细分析一下的。

对条件变一下形,等价于下面两个条件:

  • x4 = 3x1
  • x1 + x4 = x2 + x3

我们对n不同的情况来考虑

  • n=0,直接随便输出一组解就好了,比如 1 1 3 3
  • n=1,比如所给的数为a, a  a 3a 3a 就是一组解
  • n=2,所给的数为a b(a ≤ b), 我们断言b ≤ 3a时,才有解,为 a b (4a-b) 3a 。 首先若b ≤ 3a,前面所给的解是满足条件的。  若 b > 3a,则四个数中最小的一定是a,最大的一定是b,然而根据我们的条件有x4 = 3x1,即b = 3a,导出矛盾,所以无解。
  • n=3,设所给的三个数为a、b、c。我们只枚举有解的情况,其他情况则无解:  
    • 若c = 3a,则 a  b  (4a-b)  3a 是一组解
    • 若c ≤ 3a 且 b + c = 4a, 这时 a  b  c  3a 是一组解
    • 若c是3的倍数 且 a + b = ,  (c / 3)  a  b  c,是一组解
  • n=4直接判断是否满足题目要求条件就好了

代码也比较短,只有50多行。

 1 #include <cstdio>
 2 #include <algorithm>
 3 using namespace std;
 4
 5 int n, a[4], ans[4];
 6
 7 bool solve()
 8 {
 9     switch(n)
10     {
11         case 0:
12             ans[0] = ans[1] = 1, ans[2] = ans[3] = 3;
13             return true;
14         case 1:
15             ans[0] = a[0], ans[1] = ans[2] = 3 * a[0];
16             return true;
17         case 2:
18             if(a[1] <= a[0] * 3)
19             {
20                 ans[0] = a[0] * 3;
21                 ans[1] = a[0] * 4 - a[1];
22                 return true;
23             }
24             return false;
25         case 3:
26             if(a[2] == a[0] * 3)
27                 { ans[0] = a[0] * 4 - a[1]; return true; }
28             if(a[2] <= a[0] * 3 && a[1] + a[2] == a[0] * 4)
29                 { ans[0] = a[0] * 3; return true; }
30             if(a[2] % 3 == 0 && a[0] + a[1] == a[2]/3*4)
31                 { ans[0] = a[2] / 3; return true; }
32             break;
33         case 4:
34             if(a[0] + a[3] == a[1] + a[2] && a[0] * 3 == a[3])
35                 return true;
36     }
37     return false;
38 }
39
40 int main(void)
41 {
42     scanf("%d", &n);
43     for(int i = 0; i < n; ++i) scanf("%d", &a[i]);
44     sort(a, a + n);
45     if(solve())
46     {
47         printf("YES\n");
48         for(int i = 0; i < 4-n; ++i) printf("%d\n", ans[i]);
49     }
50     else printf("NO\n");
51
52     return 0;
53 }

代码君

C(暴力)

题意:

Master Yang 要去打败一个怪兽(Monster), 他和怪兽都有血量HP,攻击力ATK和防御力DEF。

每个时刻,怪兽使杨大师血量减少 max{0, ATKM - DEFY}, 同样地, 杨大师对怪兽造成的伤害为 max{0, ATKY - DEFM}

如果某一时刻HPY > 0 且 HPM ≤ 0,则视为将怪兽打败。

为了能够打败怪兽,杨大师可以去商店购买HP、ATK和DEF。

现给出杨大师和怪兽的HP、ATK和DEF,和购买每点HP、ATK和DEF所需要消耗的金币,求能够打败怪兽所需要的最少的金币。

分析:

因为数据范围很小,所以暴力是完全可以的。

我们枚举可能购买的攻击力和防御力,然后算出打败怪兽后的剩余HP,如果HP少于1,那么就要购买相应的补回来。然后取每次总花费的最小值。

 1 #include <cstdio>
 2 #include <algorithm>
 3 using namespace std;
 4
 5 int main(void)
 6 {
 7     int y[3], m[3], price[3], ans = 2000000000;
 8     for(int i = 0; i < 3; ++i) scanf("%d", &y[i]);
 9     for(int i = 0; i < 3; ++i) scanf("%d", &m[i]);
10     for(int i = 0; i < 3; ++i) scanf("%d", &price[i]);
11
12     for(int buyatk = 0; buyatk <= 200; ++buyatk)
13         for(int buydef = 0; buydef <= 200; ++buydef)
14         {
15             int crtatk = y[1] + buyatk;
16             int crtdef = y[2] + buydef;
17             int hurty = max(0, m[1] - crtdef);        //杨大师收到的伤害
18             int hurtm = max(0, crtatk - m[2]);    //怪兽收到的伤害
19             if(hurtm == 0) continue;    //打不掉怪兽的血,跳过循环
20             int k = m[0] % hurtm == 0 ? m[0]/hurtm : m[0]/hurtm + 1;
21             int LeftHP = y[0] - hurty * k;
22             int cost = price[1] * buyatk + price[2] * buydef + (1 - LeftHP > 0 ? (1 - LeftHP) * price[0] : 0);
23             ans = min(ans, cost);
24         }
25
26     printf("%d\n", ans);
27
28     return 0;
29 }

代码君

D

像这种贪心贪不出来的都感觉是DP。

在CF上扒了一个46ms的代码,也总算是看懂了。

题意:

纸条上有n个数,可以将纸条剪为若干小段(只有一个数字也可以),使得每段上的数字满足:

  • 最大值与最小值之差不超过s
  • 数字个数不少于l

分析:

从第一个数开始向左右两个方向延伸(第一个数只能往右延伸),求得一个最大的闭区间[left1, right1],使得这个区间里的数都满足第一个条件 max - min ≤ s.

如果区间的长度小于l,则无解

如果长度大于等于l,我们则求出了第一段纸片右端点的一个范围[l, right1]

第二段纸片从第 right + 1 个数向两侧延伸,这时向左延伸就有了一个界限,因为要保证第一段纸片至少有l个数,所以第二段纸片最多只能向左延伸到第l+1个数。

记此时的区间为[left2, right2],同样地,看区间的长度是否≥l来判断是否有解。这样一来,为了保证在第三段纸片延伸的时候第二段至少有l个数,所以第三段纸片至多向左延伸到left2+l+1

所以我们用last来记录每次向左延伸的界限

 1 #include <cstdio>
 2 #include <algorithm>
 3 using namespace std;
 4
 5 const int maxn = 100000 + 10;
 6 long long a[maxn], last = 0;
 7 bool flag = true;
 8
 9 int main(void)
10 {
11     //freopen("Din.txt", "r", stdin);
12
13     long long n, s, l, ans = 0;
14     scanf("%I64d%I64d%I64d", &n, &s, &l);
15     for(int i = 0; i < n; ++i) scanf("%I64d", &a[i]);
16
17     long long pos, left, right;
18     for(pos = 0; pos < n; ++pos)    //从pos位置开始延伸
19     {
20         long long maxm, minm, cnt = 1;    //区间延伸过程中的最小值和最大值,以及区间中元素的个数
21
22         maxm = a[pos], minm = a[pos];
23         right = pos + 1;
24         while(right < n)
25         {
26             maxm = max(maxm, a[right]);
27             minm = min(minm, a[right]);
28             if(maxm - minm <= s) cnt++;
29             else break;
30             right++;
31         }
32         right--;
33
34         maxm = a[pos], minm = a[pos];
35         left = pos - 1;
36         while(left >= last)
37         {
38             maxm = max(maxm, a[left]);
39             minm = min(minm, a[left]);
40             if(maxm - minm <= s) cnt++;
41             else break;
42             left--;
43         }
44         left++;
45
46         if(cnt < l)
47         {
48             flag  =false;
49             break;
50         }
51         ans++;
52         last = left + l;
53         pos = right;
54     }
55
56     if(!flag) ans = -1;
57     printf("%I64d\n", ans);
58
59     return 0;
60 }

代码君

E(数论+构造)

题意:

给出一个正整数n,问是否存在一个 1~n的排列,使得前i个数的乘积模上n的余数得到的序列是0~n-1的一个排列。

分析:

当n为1、4和素数的时候有解,构造方法是用 (i+1)*(i的逆元)%n 填充当前的数。

这道题先留着,等我比较系统地学习数论以后在给出严格证明以及代码。

时间: 2024-10-07 06:08:57

CodeForces Round #278 (Div.2) (待续)的相关文章

Codeforces Round #278 (Div. 2) b

/**  *  * @brief Codeforces Round #278 (Div. 2) b  * @file b.c  * @author mianma  * @created 2014/11/24 17:52  * @edited  2014/11/18 17:52  * @type brute  *   * @note   *          declare k >= 0;  *              then   *                  x1 = k  *   

Codeforces Round #278 (Div. 2) d

/**  * @brief Codeforces Round #278 (Div. 2) d  * @file d.c  * @author 面码  * @created 2014/11/26 10:07  * @edited  2014/11/26 10:07  * @type dp   * @note  *      自己的TL了,看了别人代码写的  *      该代码主要是在dp的基础上使用stl来提速  *      dp需辅助提速,但内存又不能爆掉是该题目的卡点 = =  */ #i

Codeforces Round #278 (Div. 2) c

/**  * @brief Codeforces Round #278 (Div. 2) c  * @file c.c  * @author 面码  * @created 2014/11/25 14:15  * @edited  2014/11/25 14:15  * @type brute  *  */ #include <stdio.h> #define max(a, b)  ((a) > (b) ? (a) : (b)) #define min(a, b)  ((a) > (

Codeforces Round #278 (Div. 1)

A A monster is attacking the Cyberland! Master Yang, a braver, is going to beat the monster. Yang and the monster each have 3 attributes: hitpoints (HP), offensive power (ATK) and defensive power (DEF). During the battle, every second the monster's H

Codeforces Round #278 (Div. 2)

A直接暴力好了. 1 #include<bits/stdc++.h> 2 typedef long long ll; 3 using namespace std; 4 5 int pan(ll x) 6 { 7 while (x) 8 { 9 if (x%10==8) return 1; 10 x/=10; 11 } 12 return 0; 13 } 14 15 int main() 16 { 17 ll n; 18 cin>>n; 19 for (int i=1;i<=1

Codeforces Round #288 (Div. 2) 待续

A. Pasha and Pixels ( 暴力 ) 题意:给一个n*m的矩阵染色(初始为全白),如果在k步之内染出一个2*2的矩阵,输出最小步数,否则输出0 分析:brute force #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> using namespace std; int M[ 1010 ][ 1010 ]; int step, r, c, k

Codeforces Round #278 (Div. 2) B. Candy Boxes [brute force+constructive algorithms]

哎,最近弱爆了,,,不过这题还是不错滴~~ 要考虑完整各种情况 8795058                 2014-11-22 06:52:58     njczy2010     B - Candy Boxes             GNU C++     Accepted 31 ms 4 KB 8795016                 2014-11-22 06:48:15     njczy2010     B - Candy Boxes             GNU C+

Codeforces Round #279 (Div. 2) ABCD

Codeforces Round #279 (Div. 2) 做得我都变绿了! Problems # Name     A Team Olympiad standard input/output 1 s, 256 MB  x2377 B Queue standard input/output 2 s, 256 MB  x1250 C Hacking Cypher standard input/output 1 s, 256 MB  x740 D Chocolate standard input/

Codeforces Round #428 (Div. 2)

Codeforces Round #428 (Div. 2) A    看懂题目意思就知道做了 #include<bits/stdc++.h> using namespace std; #pragma comment(linker, "/STACK:102400000,102400000") #define rep(i,a,b) for (int i=a; i<=b; ++i) #define per(i,b,a) for (int i=b; i>=a; --i