CodeForces 518E - Darth Vader and Tree(思路)
题意:给定一个n(1 <= n <= 10^5)长度的序列,其中有不确定的数字为'?',从前往后,每相邻k项加起来可得到一个n - k + 1长度的新序列,求是否存在一种解满足:
1、使这个n - k + 1的新序列递增;
2、如果有多解,求一种解使的所有数绝对值加起来最小。
若存在,则输出这个序列,否则输出"Incorrect sequence"。
每相邻k项加起来,例如a1,a2,a3,a4,每3项的话,是否满足递增即就是看是否有a1 + a2 + a3 < a2 + a3 + a4,化简后即a1 < a4,所以每隔k项必须递增。其次,如果有多解,那么让其中这些带问号的数的绝对值尽量靠近0,题目中还可能出现多个问号连在一起,对于这种情况需要看整段的前驱和后继。
一遍过,但代码写的挺麻烦,讨论情况太多了,以后要多学会汇总情况。
#include<cstdio> #include<cstring> #include<cctype> #include<cstdlib> #include<cmath> #include<iostream> #include<sstream> #include<iterator> #include<algorithm> #include<string> #include<vector> #include<set> #include<map> #include<deque> #include<queue> #include<stack> #include<list> #define fin freopen("in.txt", "r", stdin) #define fout freopen("out.txt", "w", stdout) #define pr(x) cout << #x << " : " << x << " " #define prln(x) cout << #x << " : " << x << endl #define Min(a, b) a < b ? a : b #define Max(a, b) a < b ? b : a typedef long long ll; typedef unsigned long long llu; const int INT_INF = 0x3f3f3f3f; const int INT_M_INF = 0x7f7f7f7f; const ll LL_INF = 0x3f3f3f3f3f3f3f3f; const ll LL_M_INF = 0x7f7f7f7f7f7f7f7f; const double pi = acos(-1.0); const double EPS = 1e-6; const int dr[] = {0, 0, -1, 1, -1, -1, 1, 1}; const int dc[] = {-1, 1, 0, 0, -1, 1, -1, 1}; const ll MOD = 1e9 + 7; const int MAXN = 100 + 10; const int MAXT = 100000 + 10; using namespace std; int n, k, a[MAXT]; int main(){ while(scanf("%d%d", &n, &k) == 2){ memset(a, INT_INF, sizeof a); char s[20]; for(int i = 0; i < n; ++i){ scanf("%s", s); if(s[0] == '?') continue; sscanf(s, "%d", &a[i]); } bool flag = true; for(int i = 0; i < k; ++i){ int l = i, alllen = 0; for(int j = i; j < n; j += k){ ++alllen; if(a[j] == INT_INF) continue; if(j == l){ if(j != i && a[j] <= a[j - k]){ flag = false; goto op; } l = j + k; continue; } if(l - k < 0){ int tmp, len = (j - i) / k; if(len % 2) tmp = Min(len / 2, a[j] - 1); else tmp = Min(len / 2 - 1, a[j] - 1); for(int u = j - k; u >= i; u -= k) a[u] = tmp--; l = j + k; } else{ int tmp, len = (j - l) / k; if(len > a[j] - a[l - k] - 1){ flag = false; goto op; } if(len % 2){ tmp = Min(len / 2, a[j] - 1); if(tmp - len + 1 <= a[l - k]) tmp = a[l - k] + len; } else{ tmp = Min(len / 2 - 1, a[j] - 1); if(tmp - len + 1 <= a[l - k]) tmp = a[l - k] + len; } for(int u = j - k; u >= l; u -= k) a[u] = tmp--; l = j + k; } } if(l < n){ if(l - k < 0){ int tmp = -alllen / 2; for(int u = i; u < n; u += k) a[u] = tmp++; } else{ int len = (n - l) / k; int tmp = Max(-len / 2, a[l - k] + 1); for(int u = l; u < n; u += k) a[u] = tmp++; } } } op: if(!flag) printf("Incorrect sequence\n"); else{ for(int i = 0; i < n; ++i){ if(i) printf(" "); printf("%d", a[i]); } printf("\n"); } } return 0; }