Technocup 2019 - Elimination Round 2

http://codeforces.com/contest/1031

(如果感觉一道题对于自己是有难度的,不要后退,懂0%的时候敲一遍,边敲边想,懂30%的时候敲一遍,边敲边想,懂60%的时候敲一遍,边敲边想,(真实情况是你其实根本不用敲那么多遍……),然后,这道题你就差不多可以拿下了ψ(`?′)ψ)

(IO模板在最后的蛋里)

A. Golden Plate

n*m矩形,最外圈为第一圈,间隔着选k个圈,问总共占多少给格子

每圈贡献=2n‘+2m‘-4,圈圈长宽以-4递减下去

public static void main(String[] args) {
        IO io=new IO();
        int n=io.nextInt(),m=io.nextInt(),k=io.nextInt();
        long ans=0;
        while (k-->0){
            ans+=2*n+2*m-4;
            n-=4;m-=4;
        }
        io.println(ans);
    }

B. Curiosity Has No Limits

给你长度为n-1的两个数列,问是否存在长度为n的数列t,满足ai=ti|ti+1&&bi=ti&ti+1,三个数列的元素都属于[0,3]

元素太少了,一开始想直接打表,但i、j到底哪个先哪个后不知道,所以从找规律入手

 1                 System.out.println(i+" "+j+" "+(i|j)+" "+(i&j));
 2 //对应ti、ti+1、ai、bi
 3 0 0 0 0
 4 0 1 1 0
 5 0 2 2 0
 6 0 3 3 0
 7 1 0 1 0
 8 1 1 1 1
 9 1 2 3 0
10 1 3 3 1
11 2 0 2 0
12 2 1 3 0
13 2 2 2 2
14 2 3 3 2
15 3 0 3 0
16 3 1 3 1
17 3 2 3 2
18 3 3 3 3

发现ti + ti+1==ai + bi,可以枚举t[0],看是否得到合法的数列t

 1  public static void main(String[] args) {
 2         IO io = new IO();
 3         int n = io.nextInt();
 4         int[] a = new int[n];
 5         int[] b = new int[n];
 6         int[] t = new int[n];
 7         for (int i = 0; i < n - 1; i++) a[i] = io.nextInt();
 8         for (int i = 0; i < n - 1; i++) b[i] = io.nextInt();
 9         OUT:
10         for (int i = 0; i < 4; i++) {
11             t[0] = i;
12             for (int j = 1; j < n; j++) {
13                 t[j] = a[j - 1] + b[j - 1] - t[j - 1];
14                 if ((t[j] | t[j - 1]) != a[j - 1] ||
15                         (t[j] & t[j - 1]) != b[j - 1]) continue OUT;
16             }
17             io.println("Yes");
18             for (int j = 0; j < n; j++) io.print(t[j] + " ");
19             return;
20         }
21         io.println("No");
22     }

C. Cram Time

给你两个数a、b,输出元素总个数最多的且累加和分别不超过a、b的两组数,其中每个数只能用一次

关键点在于当n是1+2+……+n<=a+b的最大的n时,1到n的所有数都一定选得上,只要对其中一个数从大到小取就可以保证

 1 public static void main(String[] args) {
 2         IO io = new IO();
 3         int a = io.nextInt(), b = io.nextInt(), cnt = 0, n = 0;
 4         long l = 1, r = a + b, mid;
 5         while (l <= r) {
 6             mid = (l + r) / 2;
 7             if (a + b < (mid + 1) * mid / 2) {
 8                 r = mid - 1;
 9             } else {
10                 l = mid + 1;
11                 n = (int) mid;
12             }
13         }
14         int[] vis = new int[n + 1];
15         for (int i = n; i >= 1; i--)
16             if (a >= i) {
17                 a -= i;
18                 cnt++;
19                 vis[i] = 1;
20             }
21         io.println(cnt);
22         for (int i = 1; i <= n; i++) if (vis[i] == 1) io.print(i + " ");
23         io.println("\n" + (n - cnt));
24         for (int i = 1; i <= n; i++) if (vis[i] == 0) io.print(i + " ");
25         io.close();
26     }

D. Minimum path

有一个由小写字母填满的n*n矩阵,你可以改变不超过k个字母,使从(1,1)到(n,n)的字典序最小,你只能往右走或往下走

k全部用来把前面非‘a‘字符换成’a‘。搜索从用完k后获得长度最长‘a‘串开始。ans[i]表示答案的第i个字符,对于每个ans[i],搜索所有i可能的位置,取其最小值。因为对于每个特定的长度i,其末位置不会和长度i-1的末位置重叠(如下图),所以长度i得到的末尾点j,i-j+1,vis[j][i-j+1]表示为长度为i时该点是否可达。

0 1 2 3 4
1 2 3 4 5
2 3 4 5 6
3 4 5 6 7
4 5 6 7 8 
 1  public static void main(String[] args) {
 2         IO io = new IO();
 3         int n = io.nextInt(), k = io.nextInt();
 4
 5         int[][] a = new int[c][c];
 6         int[][] dp = new int[c][c];
 7         int[][] vis = new int[c][c];
 8         int[] ans = new int[c * 2];
 9
10         for (int i = 1; i <= n; i++) for (int j = 1; j <= n; j++) a[i][j] = io.nextChar();
11         int len = 0;
12         //【初始化一定不要偷懒】
13         vis[1][1] = 1;
14         for (int i = 1; i <= n; i++)
15             for (int j = 1; j <= n; j++) {
16                 //【这里也是一样,不要贪图代码短】
17                 if (i == 1 && j == 1) dp[1][1] = 0;
18                 else if (i == 1) dp[1][j] = dp[1][j - 1];
19                 else if (j == 1) dp[i][1] = dp[i - 1][1];
20                 else dp[i][j] = Math.min(dp[i - 1][j], dp[i][j - 1]);
21                 if (a[i][j] != ‘a‘) dp[i][j]++;
22                 if (dp[i][j] <= k) {
23                     vis[i + 1][j] = vis[i][j + 1] = 1;
24                     len = Math.max(i + j - 1, len);
25                 }
26             }
27         Arrays.fill(ans, ‘z‘);
28         Arrays.fill(ans, 1, len + 1, ‘a‘);
29         for (int i = len + 1; i <= 2 * n - 1; i++) {
30             for (int j = 1; j <= n; j++)
31                 if (1 <= i - j + 1 && i - j + 1 <= n && vis[j][i - j + 1] == 1)
32                     ans[i] = Math.min(ans[i], a[j][i - j + 1]);
33             //因为最小点可能不止一个,所以不能只记录一个点
34             for (int j = 1; j <= n; j++)
35                 if (1 <= i - j + 1 && i - j + 1 <= n && vis[j][i - j + 1] == 1
36                         && a[j][i - j + 1] == ans[i])
37                     vis[j + 1][i - j + 1] = vis[j][i - j + 2] = 1;
38         }
39         for (int i = 1; i <= 2 * n - 1; i++) io.print((char) ans[i]);
40     }

E. Triple Flips

给你长度为n的01串,你可以对其进行不超过n/3+12次操作将其变成全0串,该操作为选三个间隔相等的数将其翻转(0->1,1->0),如果存在解,请打印出所有操作数字的下标

关键思想是每次保证最左边或最右边的三个数为0,字符串过小时枚举每一种情况。

  1     private static final int c = (int) (1e5 + 10);
  2     static IO io = new IO();
  3     static int n;
  4     static int[] a = new int[c];
  5     //一边操作一边记录
  6     static ArrayList<int[]> ans = new ArrayList<>();
  7
  8     static void solve0(int l, int r) {
  9         ArrayList<int[]> p = new ArrayList<>();
 10         int[] t = new int[c];
 11         int a1, a2;
 12
 13         for (int i = l; i <= r; i++) for (int j = i + 2; j <= r; j += 2) p.add(new int[]{i, j});
 14         OUT:
 15         for (int i = 0; i < 1 << p.size(); i++) {
 16             System.arraycopy(a, l, t, l, r - l + 1);
 17             for (int j = 0; j < p.size(); j++)
 18                 if ((i >> j & 1) == 1) {
 19                     a1 = p.get(j)[0];
 20                     a2 = p.get(j)[1];
 21                     t[a1] ^= 1;
 22                     t[a2] ^= 1;
 23                     t[a1 + a2 >> 1] ^= 1;
 24                 }
 25             for (int j = l; j <= r; j++) if (t[j] == 1) continue OUT;
 26             for (int j = 0; j < p.size(); j++)
 27                 if ((i >> j & 1) == 1) ans.add(p.get(j));
 28
 29             io.println("YES");
 30             io.println(ans.size());
 31             for (int[] v : ans) io.println(v[0] + " " + (v[0] + v[1] >> 1) + " " + v[1]);
 32             return;
 33         }
 34         io.println("NO");
 35     }
 36
 37     //坚定不移保证左三或右三全为0
 38     static void solve(int l, int r) {
 39         //flip需要长度至少为7
 40         if (r - l + 1 < 7) {
 41             while (l > 1 && r - l + 1 < 8) l--;
 42             while (r < n && r - l + 1 < 8) r++;
 43             solve0(l, r);
 44             return;
 45         }
 46         if (a[l] == 0) {
 47             solve(l + 1, r);
 48             return;
 49         }
 50         if (a[r] == 0) {
 51             solve(l, r - 1);
 52             return;
 53         }
 54         //111……
 55         if (a[l + 1] == 1 && a[l + 2] == 1) {
 56             flip_add(l, l + 2);
 57             solve(l + 3, r);
 58             return;
 59         }
 60         //……111
 61         if (a[r - 1] == 1 && a[r - 2] == 1) {
 62             flip_add(r - 2, r);
 63             solve(l, r - 3);
 64             return;
 65         }
 66         //101……
 67         if (a[l] == 1 && a[l + 2] == 1) {
 68             flip_add(l, l + 4);
 69             solve(l + 3, r);
 70             return;
 71         }
 72         //……101
 73         if (a[r - 2] == 1 && a[r] == 1) {
 74             flip_add(r - 4, r);
 75             solve(l, r - 3);
 76             return;
 77         }
 78         //100……翻转分别为l、l+2、l+4,目标是结果为000
 79         if (a[l + 1] == 0 && a[l + 2] == 0) {
 80             flip_add(l, l + 6);
 81             solve(l + 3, r);
 82             return;
 83         }
 84         //……001
 85         if (a[r - 1] == 0 && a[r - 2] == 0) {
 86             flip_add(r - 6, r);
 87             solve(l, r - 3);
 88             return;
 89         }
 90         //110……和……011
 91         if ((r - l + 1) % 2 == 1) {
 92             flip_add(l, r);
 93             flip_add(l + 1, r - 1);
 94             solve(l + 3, r - 3);
 95         } else {
 96             flip_add(l, r - 1);
 97             flip_add(l + 1, r);
 98             solve(l + 3, r - 3);
 99         }
100     }
101
102     public static void main(String[] args) {
103         n = io.nextInt();
104         for (int i = 1; i <= n; i++) a[i] = io.nextInt();
105         solve(1, n);
106     }111
112     //0变1,1变0
113     static void flip_add(int l, int r) {
114         a[l] ^= 1;
115         a[r] ^= 1;
116         a[l + r >> 1] ^= 1;
117         ans.add(new int[]{l, r});
118     }

F. Familiar Operations

有正整数a、b以及两种操作:1、对其中一个数乘以某个素数,2、对其中一个数除以其素因子,问让两个数因子数相同的最小操作是多少。

彩蛋(/≧▽≦)/丢~快接~

原文地址:https://www.cnblogs.com/towerbird/p/9933746.html

时间: 2024-10-12 11:07:06

Technocup 2019 - Elimination Round 2的相关文章

Codeforces Round #512 (Div. 2, based on Technocup 2019 Elimination Round 1) C. Vasya and Golden Ticket

C. Vasya and Golden Ticket time limit per test 1 second memory limit per test 256 megabytes input standard input output standard output Recently Vasya found a golden ticket - a sequence which consists of nn digits a1a2-ana1a2-an. Vasya considers a ti

[Codeforces Round #522 (Div. 2, based on Technocup 2019 Elimination Round 3)][C. Playing Piano]

http://codeforces.com/contest/1079/problem/C 题目大意:给出一个数列a[n],让构造一个满足下列条件的数列b[n]:如果a[i]>a[i-1]那么b[i]>b[i-1],如果a[i]<a[i-1]那么b[i]<b[i-1],如果a[i]==a[i-1],那么b[i]!=b[i-1].其中1<=b[i]<=5  1<=a[i]<=2*1e5. 题解:dp[i][j]表示在位置i处取j时是否成立,如果成立则dp[i][

codeforces Technocup 2017 - Elimination Round 2/Codeforces Round #380 (Div. 2, Rated, Based on Technocup 2017 - Elimination Round 2) 题解

久违的下午场,打了一场状态不错一下rank12涨了207~~~ A. Interview with Oleg 题意: 给你一个长度不超过100的串,把其中ago开头后面不接或者接gogogo...的部分全部变成*** 思路: 水水,扫 /* *********************************************** Author :devil ************************************************ */ #include <cstdi

Technocup 2017 - Elimination Round 1 (Unofficially Open for Everyone, Rated for Div. 2) B

Vasily exited from a store and now he wants to recheck the total price of all purchases in his bill. The bill is a string in which the names of the purchases and their prices are printed in a row without any spaces. Check has the format "name1price1n

Technocup 2017 - Elimination Round 1 (Unofficially Open for Everyone, Rated for Div. 2) A

Vasily has a number a, which he wants to turn into a number b. For this purpose, he can do two types of operations: multiply the current number by 2 (that is, replace the number x by 2·x); append the digit 1 to the right of current number (that is, r

Technocup 2017 - Elimination Round 1 (Unofficially Open for Everyone, Rated for Div. 2) C

This is an interactive problem. You should use flush operation after each printed line. For example, in C++ you should usefflush(stdout), in Java you should use System.out.flush(), and in Pascal - flush(output). In this problem you should guess an ar

codeforces Codeforces Round #380 (Div. 1, Rated, Based on Technocup 2017 - Elimination Round 2)// 二分的题目硬生生想出来ON的算法

A. Road to Cinema 很明显满足二分性质的题目. 题意:某人在起点处,到终点的距离为s. 汽车租赁公司提供n中车型,每种车型有属性ci(租车费用),vi(油箱容量). 车子有两种前进方式 :①. 慢速:1km消耗1L汽油,花费2分钟. ②.快速:1km消耗2L汽油,花费1分钟. 路上有k个加油站,加油不需要花费时间,且直接给油箱加满. 问在t分钟内到达终点的最小花费是多少?(租车子的费用)  若无法到达终点,输出-1 不谈二分的写法.. 我们考虑离散化可修改的点  和限制的点位置

【模拟】 Codeforces Round #434 (Div. 1, based on Technocup 2018 Elimination Round 1) C. Tests Renumeration

题意:有一堆数据,某些是样例数据(假设X个),某些是大数据(假设Y个),但这些数据文件的命名非常混乱.要你给它们一个一个地重命名,保证任意时刻没有重名文件的前提之下,使得样例数据命名为1~X,大数据命名为X+1~X+Y. 先把未使用的名字压进两个栈. 分为三轮:第一轮把占用了对方名字的样例数据以及占用了对方名字的大数据放进两个队列,然后不断反复尝试对这两个队列进行出队操作,每次将占用对方名字的改成一个未被使用的正确名字(从栈里取出),然后将占用的名字压进另一个栈.由于每个数据只会出队一次,所以是

cf 20190307 Codeforces Round #543 (Div. 2, based on Technocup 2019 Final Round)

B. Mike and Children time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standard output Mike decided to teach programming to children in an elementary school. He knows that it is not an easy task to interest