Codeforces #148 div2
2015-06-11 20:00:59
【传送门】
A题:数学题,简单枚举。
#include <cstdio> #include <cstring> #include <cstdlib> #include <cmath> #include <vector> #include <map> #include <set> #include <stack> #include <queue> #include <string> #include <iostream> #include <algorithm> using namespace std; #define getmid(l,r) ((l) + ((r) - (l)) / 2) #define MP(a,b) make_pair(a,b) #define PB(a) push_back(a) typedef long long ll; typedef pair<int,int> pii; const double eps = 1e-8; const int INF = (1 << 30) - 1; ll x,y,k,n; int main(){ scanf("%I64d%I64d%I64d",&y,&k,&n); bool flag = false; for(int i = 1; ; ++i){ x = (ll)i * k - y; if(x + y > n) break; if(x >= 1){ printf("%I64d ",x); flag = true; } } if(!flag) printf("-1\n"); else puts(""); return 0; }
B题:模拟题,注意删除操作的实现。
#include <cstdio> #include <cstring> #include <cstdlib> #include <cmath> #include <vector> #include <map> #include <set> #include <stack> #include <queue> #include <string> #include <iostream> #include <algorithm> using namespace std; #define getmid(l,r) ((l) + ((r) - (l)) / 2) #define MP(a,b) make_pair(a,b) #define PB(a) push_back(a) typedef long long ll; typedef pair<int,int> pii; const double eps = 1e-8; const int INF = (1 << 30) - 1; int n,q; char ts[110],s[110]; int vis[110]; int l,r,cnt[20]; int main(){ scanf("%d%d",&n,&q); scanf("%s",s + 1); for(int i = 1; i <= n; ++i) ts[i] = s[i]; for(int o = 1; o <= q; ++o){ scanf("%d%d",&l,&r); int p = l,d = 1,pre = -1; memset(cnt,0,sizeof(cnt)); memset(vis,0,sizeof(vis)); memcpy(s,ts,sizeof(ts)); while(p >= l && p <= r){ if(vis[p]){ p += d; continue; } if(s[p] >= '0' && s[p] <= '9'){ cnt[s[p] - '0']++; s[p]--; if(s[p] < '0') vis[p] = 1; p += d; pre = -1; } else{ if(pre != -1) vis[pre] = 1; if(s[p] == '>') d = 1; else d = -1; pre = p; p += d; } } for(int i = 0; i <= 9; ++i) printf("%d ",cnt[i]); puts(""); } return 0; }
C题:思维题,题目要求的是不存在任意子串其异或值是0,其实也就是所有前缀异或和的值互不相同(如果某两个前缀异或和值相同,那么他们相差的
那部分的异或和必定是0,思考),因为加的数是0~2^m-1间任意的,所以可以任意构造出所有可能的前缀异或和,所有可能是
#include <cstdio> #include <cstring> #include <cstdlib> #include <cmath> #include <vector> #include <map> #include <set> #include <stack> #include <queue> #include <string> #include <iostream> #include <algorithm> using namespace std; #define getmid(l,r) ((l) + ((r) - (l)) / 2) #define MP(a,b) make_pair(a,b) #define PB(a) push_back(a) typedef long long ll; typedef pair<int,int> pii; const double eps = 1e-8; const int INF = (1 << 30) - 1; const ll mod = 1000000009LL; int n,m; int main(){ scanf("%d%d",&n,&m); ll val = 1; for(int i = 1; i <= m; ++i) val = (val * 2LL) % mod; val = (val - 1 + mod) % mod; ll ans = 1; for(int i = 1; i <= n; ++i){ ans = (ans * val) % mod; val = (val - 1 + mod) % mod; } printf("%I64d\n",ans); return 0; }
D题:数学题,要求将数列分两部分,考虑任意数对的和,如果两数在不同的部分,则在和上加上 h,要求让数对和的最大值最小值的差最小。
首先是对数列进行排序,考虑了四种情况:(1)数较小的部分只有一个(2)数较小的部分为空(3)数较小的部分只有两个(4)数较小的有n-1个
设数列为 a1,a2,....,an,(1)只用考虑 a1+a2+h , a2+a3 , an-1+an,a1+an+h (2)只用考虑a1+a2 , an-1+an (3)只用考虑a1+a2 , an-1+ an , a2+an+h (4)只用考虑 a1+a2 ,an-1+an+h
#include <cstdio> #include <cmath> #include <iostream> #include <algorithm> using namespace std; const int INF = (1 <<30) - 1; int n,h,A[100010],B[100010]; bool Check(int &ans,int res){ if(res < ans){ ans = res; return true; } return false; } int main(){ scanf("%d%d",&n,&h); for(int i = 1; i <= n; ++i) scanf("%d",A + i),B[i] = A[i]; sort(A + 1,A + n +1); int ans = INF,tmin,tmax,f; tmin = min(A[1]+A[2]+h,A[2]+A[3]); tmax = max(A[n-1]+A[n],A[1]+A[n]+h); if(Check(ans,tmax - tmin)) f = 1; tmin = A[1]+A[2]; tmax = A[n-1]+A[n]; if(Check(ans,tmax - tmin)) f = 2; tmax = max(A[n-1]+A[n],A[2]+A[n]+h); if(Check(ans,tmax - tmin)) f = 3; tmax = A[n-1]+A[n]+h; if(Check(ans,tmax - tmin)) f = 4; printf("%d\n",ans); if(f == 1){ int head = 1; for(int i = 1; i <= n; ++i){ if(head && B[i] == A[1]) printf("1 "),head = 0; else printf("2 "); } puts(""); } if(f == 2){ for(int i = 1; i <= n; ++i) printf("1 "); puts(""); } if(f == 3){ int h1 = 1,h2 = 1; for(int i = 1; i <= n; ++i){ if(h1 && B[i] == A[1]) printf("1 "),h1 = 0; else if(h2 && B[i] == A[2]) printf("1 "),h2 = 0; else printf("2 "); } puts(""); } if(f == 4){ int head = 1; for(int i = 1; i <= n; ++i){ if(head && B[i] == A[n]) printf("1 "),head = 0; else printf("2 "); } puts(""); } return 0; }