2016-2017 ACM-ICPC CHINA-Final Solution
Problem A. Number Theory Problem
Solved.
水。
1 #include<bits/stdc++.h> 2 3 using namespace std; 4 5 const int maxn = 1e5 + 10; 6 7 typedef long long ll; 8 9 int n; 10 ll arr[maxn], ans[maxn]; 11 12 void Init() 13 { 14 arr[0] = 1; 15 for(int i = 1; i <= maxn; ++i) 16 { 17 arr[i] = (arr[i - 1] * 2) % 7; 18 ans[i] = ans[i - 1]; 19 if(arr[i] == 1) ans[i]++; 20 } 21 } 22 23 int main() 24 { 25 Init(); 26 int t; 27 scanf("%d",&t); 28 for(int cas = 1; cas <= t; ++cas) 29 { 30 scanf("%d", &n); 31 printf("Case #%d: %lld ", cas, ans[n]); 32 } 33 return 0; 34 }
Problem B. Hemi Palindrome
Unsolved.
题意:
定义$Hemi Palindrome$ 为去掉所有奇数位上的数字后是回文串或者去掉所有偶数位上的数是回文串,给出一个长度$N$
构造一个字典序最小的$Hemi Palindrome$
Problem C. Mr. Panda and Strips
Upsolved.
题意:
选择序列中两段不相交的连续区间,要求这两段区间并没有重复数字,求最长长度。
思路:
双指针枚举第一个区间,然后再左段和右段再双指针枚举最长的合并区间
我们考虑双指针扩展右指针的过程中,也可以更新答案
但是对于已经在前一个左指针上扩展过的,就没有必要扩展了。
.....L......R........
我们考虑枚举的时候是这样的
那么L.......R 这一段没有必要再检查是否有更大的答案,因为如果有,那么必然是L - 1........R 是更大的
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 #define N 1010 5 #define M 100010 6 int t, n, a[N]; 7 int vis[M][2]; 8 9 int solve(int ql, int qr) 10 { 11 int res = 0; 12 for (int i = ql, r = ql - 1; i <= qr; ++i) 13 { 14 if (r < i) r = i - 1; 15 while (r < qr && !vis[a[r + 1]][0] && !vis[a[r + 1]][1]) 16 { 17 ++r; 18 vis[a[r]][1] = 1; 19 } 20 res = max(res, r - i + 1); 21 vis[a[i]][1] = 0; 22 } 23 return res; 24 } 25 26 int main() 27 { 28 scanf("%d", &t); 29 for (int kase = 1; kase <= t; ++kase) 30 { 31 printf("Case #%d: ", kase); 32 scanf("%d", &n); 33 for (int i = 1; i <= n; ++i) scanf("%d", a + i); 34 memset(vis, 0, sizeof vis); 35 int res = 0; 36 for (int i = 1, r = 0; i <= n; ++i) 37 { 38 while (r < n && !vis[a[r + 1]][0]) 39 { 40 ++r; 41 vis[a[r]][0] = 1; 42 res = max(res, r - i + 1 + max(solve(1, i - 1), solve(r + 1, n))); 43 } 44 int tmp = max(solve(1, i - 1), solve(r + 1, n)); 45 res = max(res, r - i + 1 + tmp); 46 vis[a[i]][0] = 0; 47 } 48 printf("%d ", res); 49 } 50 return 0; 51 }