Codeforces Round #176 (Div. 2)
http://codeforces.com/contest/287
A:水。。。
B: 数学+贪心 或者 二分
题意:
给你k-1个如图形状的水管,他们的出水口分别为2,4,....k,只有一个总出水口,然后让你判断他们之间连接组成出水口为n的需要的最少的谁数,如果不能输出-1;
开始我用数学+贪心做的,结果忘记考虑一种情况WA了。
思路:
首先如果k>n我们只需要选择一个即可,这里注意n可能会出现1,1是不可能出来的,就是应为这里错了。然后我们计算总数,这里能够组和出来的最多的出水口总数为sum = (k*(k - 1))/2 + 1;
如果sum < n 那肯不行了,如果等于>= n那必定存在解,我们首先利用最大的来组成n首先选k,k - 1,k - 2,如果加到x出现了大与n的情况,那么我们肯定可以从那些小于x里面出一个来组成n,这里我计算了sum - n的差值,然后计算1 + 2 + x + .. = cha的x值,这就就是选择最多的组成cha的所需要的的谁数,然后看k - 1 - x就是用的最少的组成n的数量。
(x + 1)*x/2 == cha解一元二次方程即可。
二分的话,就是二分选择的最小的哪个水管,然后从最大的往前加。选则大于等n的最大的mid
数学:
#include <iostream> #include <cstdio> #include <cmath> #include <vector> #include <cstring> #include <algorithm> #include <string> #include <set> #include <functional> #include <numeric> #include <sstream> #include <stack> #include <map> #include <queue> #define CL(arr, val) memset(arr, val, sizeof(arr)) #define lc l,m,rt<<1 #define rc m + 1,r,rt<<1|1 #define pi acos(-1.0) #define ll __int64 #define L(x) (x) << 1 #define R(x) (x) << 1 | 1 #define MID(l, r) (l + r) >> 1 #define Min(x, y) (x) < (y) ? (x) : (y) #define Max(x, y) (x) < (y) ? (y) : (x) #define E(x) (1 << (x)) #define iabs(x) (x) < 0 ? -(x) : (x) #define OUT(x) printf("%I64d\n", x) #define lowbit(x) (x)&(-x) #define Read() freopen("din.txt", "r", stdin) #define Write() freopen("dout.txt", "w", stdout); #define M 307 #define N 4100007 using namespace std; ll n,k; int main() { // Read(); int i,j; while (cin>>n>>k) { if (k >= n) { if (n >= 2) printf("1\n"); else printf("0\n"); continue; } else { ll sum = (k*(k - 1))/2 + 1; if (sum < n) printf("-1\n"); else { ll cha = sum - n; ll no = (sqrt(1LL + 8LL*cha) - 1)/2; printf("%I64d\n",k - 1 - no); } } } return 0; }
二分:
#include <iostream> #include <cstdio> #include <cmath> #include <vector> #include <cstring> #include <algorithm> #include <string> #include <set> #include <functional> #include <numeric> #include <sstream> #include <stack> #include <map> #include <queue> #define CL(arr, val) memset(arr, val, sizeof(arr)) #define lc l,m,rt<<1 #define rc m + 1,r,rt<<1|1 #define pi acos(-1.0) #define ll __int64 #define L(x) (x) << 1 #define R(x) (x) << 1 | 1 #define MID(l, r) (l + r) >> 1 #define Min(x, y) (x) < (y) ? (x) : (y) #define Max(x, y) (x) < (y) ? (y) : (x) #define E(x) (1 << (x)) #define iabs(x) (x) < 0 ? -(x) : (x) #define OUT(x) printf("%I64d\n", x) #define lowbit(x) (x)&(-x) #define Read() freopen("din.txt", "r", stdin) #define Write() freopen("dout.txt", "w", stdout); #define M 307 #define N 4100007 using namespace std; ll n,k,L,R; int main() { // Read(); while (cin>>n>>k) { if (n == 1) { printf("0\n"); continue; } L = 2; R = k; int ans = -1; while (L <= R) { ll mid = (L + R)/2; ll sum = (k + mid - 2)*(k - mid + 1)/2 + 1; // printf("%I64d %I64d\n",mid,sum); if (sum >= n) { ans = mid; L = mid + 1; } else R = mid - 1; } if (ans == -1) printf("-1\n"); else printf("%I64d\n", k - ans + 1); } return 0; }
C:
题意:
Ppi = n - i + 1; 给出n求一个满足的p数组。 如果不存在,输出-1
思路:
假设p1 = k;
Pp1 = n-> pk = n;
Ppk = n - k + 1 -> pn = n - k + 1;
Ppn - k + 1 = n - (n - k + 1) = k;
我们可以发现这里是每四个一循环。
我们让
p[i] = i + 1
p[i + 1] = pp[i] = n - i + 1;
p[n - i + 1] = pp[i + 1] = (n - i - 1) + 1 = n - i;
p[n - i] = pp[n - i + 1] = (n - n + i - 1) + 1 = i;
然后枚举即可,这里如果n%4 == 2 || 3的话是不存在结果的,代入几组数据就可以看出来。
#include <iostream> #include <cstdio> #include <cmath> #include <vector> #include <cstring> #include <algorithm> #include <string> #include <set> #include <functional> #include <numeric> #include <sstream> #include <stack> #include <map> #include <queue> #define CL(arr, val) memset(arr, val, sizeof(arr)) #define lc l,m,rt<<1 #define rc m + 1,r,rt<<1|1 #define pi acos(-1.0) #define ll __int64 #define L(x) (x) << 1 #define R(x) (x) << 1 | 1 #define MID(l, r) (l + r) >> 1 #define Min(x, y) (x) < (y) ? (x) : (y) #define Max(x, y) (x) < (y) ? (y) : (x) #define E(x) (1 << (x)) #define iabs(x) (x) < 0 ? -(x) : (x) #define OUT(x) printf("%I64d\n", x) #define lowbit(x) (x)&(-x) #define Read() freopen("din.txt", "r", stdin) #define Write() freopen("dout.txt", "w", stdout); #define M 307 #define N 100007 using namespace std; int a[N]; int n; int main() { // Read(); // Write(); int i,j; while (~scanf("%d",&n)) { if (n%4 == 2 || n%4 == 3) { printf("-1\n"); continue; } for (i = 1; i <= n/2; i += 2) { a[i] = i + 1; a[i + 1] = n - i + 1; a[n - i + 1] = n - i; a[n - i] = i; } if (n&1) { a[n/2 + 1] = n/2 + 1; } for (i = 1; i < n; ++i) printf("%d ",a[i]); printf("%d\n",a[i]); } return 0; }
D:
题意:
就是给你n个数。然后 k取 [2~n] 分别执行如图操作,为你最后的结果
他的本意:
1 2 3 4 5
k == 2: 2 1 3 4 5(1放到2后边,3放到4后边)
k == 3: 1 3 2 5 4(2放到3后边,4放到5后边)
这样模拟,
我们发现没交换一次其实就是整个数组往后一道一个位置,例如k=3时,让2与4交换,然后超过了n之后4就与原来的长度+1交换,就行成了 1 3 2 5 4
这样模拟就可。
#include <iostream> #include <cstdio> #include <cmath> #include <vector> #include <cstring> #include <algorithm> #include <string> #include <set> #include <functional> #include <numeric> #include <sstream> #include <stack> #include <map> #include <queue> #define CL(arr, val) memset(arr, val, sizeof(arr)) #define lc l,m,rt<<1 #define rc m + 1,r,rt<<1|1 #define pi acos(-1.0) #define ll __int64 #define L(x) (x) << 1 #define R(x) (x) << 1 | 1 #define MID(l, r) (l + r) >> 1 #define Min(x, y) (x) < (y) ? (x) : (y) #define Max(x, y) (x) < (y) ? (y) : (x) #define E(x) (1 << (x)) #define iabs(x) (x) < 0 ? -(x) : (x) #define OUT(x) printf("%I64d\n", x) #define lowbit(x) (x)&(-x) #define Read() freopen("din.txt", "r", stdin) #define Write() freopen("dout.txt", "w", stdout); #define M 307 #define N 2000007 using namespace std; int a[N]; int n; int main() { int i,k; while (~scanf("%d",&n)) { for (i = 1; i <= n; ++i) a[i] = i; for (k = 2; k <= n; ++k) { int st = k - 1; for (i = st; i + k <= n + k - 2; i += k) { swap(a[st],a[i + k]); } swap(a[st],a[n + k - 1]); } for (i = n; i < 2*n - 1; ++i) printf("%d ",a[i]); printf("%d\n",a[2*n - 1]); } }
E:
题意:
话说,这题描述根本就看不懂。最后看了别人的代码才把题意弄懂,反过来再看题目,还是题目描述与题意扯不上关系呀。MD
这题就是给你n个数,这n个数代表了括号,整数代表左括号,负数代表右括号,给出一个p数组,全部为整数, pi = |xi| (1 ≤ i ≤ n),q数组,表明Xqi为负数。 让我们根据p和q求出满足条件的X,如果不存在输出NO
思路:
我们只要倒着用栈模拟就行,如果出现的是右括号直接放进栈去,如果出现了左括号,看看最近的栈顶的是否能够与之匹配如果不匹配,那么他在X中必定为右括号,然后这样一直匹配下去,如果最后栈顶为空,那么存在解,否则无解。
#include <iostream> #include <cstdio> #include <cmath> #include <vector> #include <cstring> #include <algorithm> #include <string> #include <set> #include <functional> #include <numeric> #include <sstream> #include <stack> #include <map> #include <queue> #define CL(arr, val) memset(arr, val, sizeof(arr)) #define lc l,m,rt<<1 #define rc m + 1,r,rt<<1|1 #define pi acos(-1.0) #define ll long long #define L(x) (x) << 1 #define R(x) (x) << 1 | 1 #define MID(l, r) (l + r) >> 1 #define Min(x, y) (x) < (y) ? (x) : (y) #define Max(x, y) (x) < (y) ? (y) : (x) #define E(x) (1 << (x)) #define iabs(x) (x) < 0 ? -(x) : (x) #define OUT(x) printf("%I64d\n", x) #define lowbit(x) (x)&(-x) #define Read() freopen("din.txt", "r", stdin) #define Write() freopen("dout.txt", "w", stdout); #define M 150 #define N 1000007 using namespace std; int a[N],st[N]; int main() { int i,j; int n,m; int x; while (~scanf("%d",&n)) { for (i = 0; i < n; ++i) scanf("%d",&a[i]); scanf("%d",&m); for (j = 0; j < m; ++j) { scanf("%d",&x); a[x - 1]*=-1; } int len = 0; for (i = n - 1; i >= 0; --i) { if (a[i] < 0) { st[len++] = a[i]; } else { if (len != 0 && st[len - 1] == -a[i]) len--; else st[len++] = (a[i] *= -1); } } if (len) printf("NO\n"); else { printf("YES\n"); for (i = 0; i < n - 1; ++i) printf("%d ",a[i]); printf("%d\n",a[i]); } } return 0; }