《Codeforces Round #643 (Div. 2)》
A:
边界就是min*max = 0的时候,显然这个时候往后就会继续保持不变.
那么对于没到的情况,暴力去找。到了就直接退出。
至于如何证明这个到0的情况次数不会太多,并不会..
Code:
#include<iostream> #include<stdio.h> #include<queue> #include<algorithm> #include<math.h> #include<stack> #include<map> #include<limits.h> #include<vector> #include<string.h> #include<string> using namespace std; typedef long long LL; typedef pair<double,double> pii; const int N = 2e5+5; const int M = 1005; const int Mod = 1e9+7; #define pi acos(-1) #define INF 1e8 #define INM INT_MIN #define pb(a) push_back(a) #define mk(a,b) make_pair(a,b) #define dbg(x) cout << "now this num is " << x << endl; #define met0(axx) memset(axx,0,sizeof(axx)); #define metf(axx) memset(axx,-1,sizeof(axx)); #define sd(ax) scanf("%d",&ax) #define sld(ax) scanf("%lld",&ax) #define sldd(ax,bx) scanf("%lld %lld",&ax,&bx) #define sdd(ax,bx) scanf("%d %d",&ax,&bx) #define sddd(ax,bx,cx) scanf("%d %d %d",&ax,&bx,&cx) #define sfd(ax) scanf("%lf",&ax) #define sfdd(ax,bx) scanf("%lf %lf",&ax,&bx) #define pr(a) printf("%d\n",a) #define plr(a) printf("%lld\n",a) LL Up(LL x) { LL ma = -1; while(x){ma = max(ma,x%10);x /= 10;} return ma; } LL Down(LL x) { LL ma = 11; while(x){ma = min(ma,x%10);x /= 10;} return ma; } LL slove(LL x) { return Up(x)*Down(x); } int main() { int t;sd(t); while(t--) { LL a,k;sldd(a,k); LL ma = slove(a),i = 1; while(ma != 0 && i < k) { i++; a = a+ma; ma = slove(a); } plr(a); } //system("pause"); return 0; }
B:
题意:注意可以有些人不参加
思路:
很显然是个贪心,一开始从大到小,这样其实难保证最优,因为可以有人不参加。
所以从小到大贪,双指针跳了半天,还是直接计数更直接....
Code:
#include<iostream> #include<stdio.h> #include<queue> #include<algorithm> #include<math.h> #include<stack> #include<map> #include<limits.h> #include<vector> #include<string.h> #include<string> using namespace std; typedef long long LL; typedef pair<double,double> pii; const int N = 2e5+5; const int M = 1005; const int Mod = 1e9+7; #define pi acos(-1) #define INF 1e8 #define INM INT_MIN #define pb(a) push_back(a) #define mk(a,b) make_pair(a,b) #define dbg(x) cout << "now this num is " << x << endl; #define met0(axx) memset(axx,0,sizeof(axx)); #define metf(axx) memset(axx,-1,sizeof(axx)); #define sd(ax) scanf("%d",&ax) #define sld(ax) scanf("%lld",&ax) #define sldd(ax,bx) scanf("%lld %lld",&ax,&bx) #define sdd(ax,bx) scanf("%d %d",&ax,&bx) #define sddd(ax,bx,cx) scanf("%d %d %d",&ax,&bx,&cx) #define sfd(ax) scanf("%lf",&ax) #define sfdd(ax,bx) scanf("%lf %lf",&ax,&bx) #define pr(a) printf("%d\n",a) #define plr(a) printf("%lld\n",a) int a[N]; int main() { int t;sd(t); while(t--) { int n;sd(n); for(int i=1;i<=n;++i) sd(a[i]); sort(a+1,a+n+1); int ans = 0,cnt = 0; for(int i=1;i<=n;++i) { cnt++; if(a[i] == cnt) ans++,cnt = 0; } pr(ans); } // system("pause"); return 0; }
C:
思路:
我们可以去枚举x的值,那么选这个x可以和y组成的x+y的边就是
[i+B,i+C].那么我们差分维护这个值,然后还原值,然后再求一次前缀和。
然后枚举z的值,对于比z大的值他们都可以和z组成三角形。所以直接前缀和统计比z大的值。
注意:数组开两倍,控制下上限。当z的值大于B+C时,说明x+y已经不可能大于z,那么就没必要枚举了,后面肯定都不可能。。
Code:
#include<iostream> #include<stdio.h> #include<queue> #include<algorithm> #include<math.h> #include<stack> #include<map> #include<limits.h> #include<vector> #include<string.h> #include<string> using namespace std; typedef long long LL; typedef pair<double,double> pii; const int N = 5e5+5; const int M = 1005; const int Mod = 1e9+7; #define pi acos(-1) #define INF 1e8 #define INM INT_MIN #define pb(a) push_back(a) #define mk(a,b) make_pair(a,b) #define dbg(x) cout << "now this num is " << x << endl; #define met0(axx) memset(axx,0,sizeof(axx)); #define metf(axx) memset(axx,-1,sizeof(axx)); #define sd(ax) scanf("%d",&ax) #define sld(ax) scanf("%lld",&ax) #define sldd(ax,bx) scanf("%lld %lld",&ax,&bx) #define sdd(ax,bx) scanf("%d %d",&ax,&bx) #define sddd(ax,bx,cx) scanf("%d %d %d",&ax,&bx,&cx) #define sfd(ax) scanf("%lf",&ax) #define sfdd(ax,bx) scanf("%lf %lf",&ax,&bx) #define pr(a) printf("%d\n",a) #define plr(a) printf("%lld\n",a) LL s[N<<1],sum[N<<1]; int main() { int A,B,C,D; sdd(A,B),sdd(C,D); for(int i=A;i<=B;++i) { s[i+B]++; s[i+C+1]--; } for(int i=A+B;i<=B+C;++i) s[i] += s[i-1]; for(int i=A+B;i<=B+C;++i) sum[i] = sum[i-1]+s[i]; LL ans = 0; for(int i=C;i<=D;++i) { if(B+C <= i) break; ans += (sum[B+C]-sum[i]); } plr(ans); system("pause"); return 0; }
D:
思路:构造
当s为奇数时:
我们令前n-1个数为2,那么最后一个数肯定是一个奇数
那么令k = s-1.这个肯定无法取得。
因为s-1为奇数,而a[n]加上前面除了第一个2也只等于s-2.再加上2就会 = s.
那么看s-k = 1。所以只要特判最后一个值是不是1就可以了。
当s为偶数时,
采取同样的思路。
2 2 2 a[n].
那么a[n]肯定是偶数。
k = s-1肯定是奇数,很显然凑不出来,s-k也肯定是奇数,很显然也凑不出来。
所以s为偶数时必定可以构造出来。
但是这里会有个问题,那就是最后一个值可能会<=0,这个时候也是不满足的。
Code:
#include<iostream> #include<stdio.h> #include<queue> #include<algorithm> #include<math.h> #include<stack> #include<map> #include<limits.h> #include<vector> #include<string.h> #include<string> using namespace std; typedef long long LL; typedef pair<double,double> pii; const int N = 1e6+5; const int M = 1005; const int Mod = 1e9+7; #define pi acos(-1) #define INF 1e8 #define INM INT_MIN #define pb(a) push_back(a) #define mk(a,b) make_pair(a,b) #define dbg(x) cout << "now this num is " << x << endl; #define met0(axx) memset(axx,0,sizeof(axx)); #define metf(axx) memset(axx,-1,sizeof(axx)); #define sd(ax) scanf("%d",&ax) #define sld(ax) scanf("%lld",&ax) #define sldd(ax,bx) scanf("%lld %lld",&ax,&bx) #define sdd(ax,bx) scanf("%d %d",&ax,&bx) #define sddd(ax,bx,cx) scanf("%d %d %d",&ax,&bx,&cx) #define sfd(ax) scanf("%lf",&ax) #define sfdd(ax,bx) scanf("%lf %lf",&ax,&bx) #define pr(a) printf("%d\n",a) #define plr(a) printf("%lld\n",a) int a[N]; int main() { int n,s;sdd(n,s); for(int i=1;i<=n;++i) a[i] = (i==n?s-2*(i-1):2); if((!(s&1) || a[n] != 1) && a[n] > 0) { printf("YES\n"); for(int i=1;i<=n;++i) printf("%d%c",a[i],i==n?'\n':' '); printf("%d\n",s-1); } else printf("NO\n"); system("pause"); return 0; }