A.Doremy's Paint
直接输出1和n即可。
代码:
- #include<bits/stdc++.h>
- using namespace std;
- #define fer(i,a,b) for(int i=a;i<=b;i++)
- #define fdr(i,a,b) for(int i=a;i>=b;i--)
- #define int long long
- #define endl '\n'
- #define ll long long
- const int N=2e5+10;
- const int mod=1e9+7;
- signed main()
- {
- ios::sync_with_stdio(0);cin.tie(0),cout.tie(0);
- int t;
- cin>>t;
- int n;
- while(t--){
- cin>>n;
- cout<<1<<' '<<n<<endl;
- }
- }
B.Doremy's Perfect Math Class
找出所有数的最大公约数,然后用所有数中的最大值a[n]除以最大公约数即可得到答案。
代码:
- #include<bits/stdc++.h>
- using namespace std;
- #define fer(i,a,b) for(int i=a;i<=b;i++)
- #define fdr(i,a,b) for(int i=a;i>=b;i--)
- #define int long long
- #define endl '\n'
- #define ll long long
- const int N=2e5+10;
- const int mod=1e9+7;
- int gcd(int x,int y){if(y==0) return x;else return gcd(y,x%y);}
- int a[N];
- signed main()
- {
- ios::sync_with_stdio(0);cin.tie(0),cout.tie(0);
- int t;
- cin>>t;
- int n;
- while(t--){
- cin>>n;
- int com=1;
- fer(i,1,n){
- cin>>a[i];
- if(i==1) com=a[1];
- if(i!=1) com=gcd(com,a[i]);
- }
- cout<<a[n]/com<<endl;
- }
- }
C.Doremy's City Construction
先对数组进行排序。对于每个数值,求出它的个数(计为mp[x]),小于它的数值的个数(计为pre),大于它的数值的个数(计为suf),取最大的(mp[x]+pre)*suf即可。考虑所有数都相同的特例,发现结果为n/2。//这次比赛时resubmission正确的话会覆盖掉第一次的正确提交,比赛快结束时本想简化一步试试的,结果覆盖掉了之前正确的提交,有点坑。
代码:
- #include<bits/stdc++.h>
- using namespace std;
- #define fer(i,a,b) for(int i=a;i<=b;i++)
- #define fdr(i,a,b) for(int i=a;i>=b;i--)
- #define int long long
- #define endl '\n'
- #define ll long long
- const int N=2e5+10;
- const int mod=1e9+7;
- int gcd(int x,int y){if(y==0) return x;else return gcd(y,x%y);}
- int a[N];
- signed main()
- {
- ios::sync_with_stdio(0);cin.tie(0),cout.tie(0);
- int t;
- cin>>t;
- int n;
- while(t--){
- cin>>n;
- map<int,int> mp;
- map<int,int> mp1;
- fer(i,1,n) cin>>a[i];
- sort(a+1,a+1+n);
- fer(i,1,n) mp[a[i]]++;
- int ans=0;
- fer(i,1,n){
- int x=a[i];
- int pos=upper_bound(a+1,a+1+n,a[i])-a;
- mp1[x]++;
- int pre=i-1,suf=n+1-pos;
- if(mp1[x]==1) ans=max(ans,(mp[x]+pre)*suf);
- }
- if(ans==0) cout<<n/2<<endl;
- else cout<<ans<<endl;
- }
- }
D.Doremy's Pegging Game
引用官方题解的解法
操作结束的状态是蓝钉不在剩余红钉所组成的多边形内,通过自己尝试,易知取到
连续的⌊n/2⌋(n/2的下取整)个红钉时结束。
设t=⌊n/2⌋。
先考虑n为奇数的情况:
结束时的状态可以看作是取了 i (t <= i <= n - 2)个连续个红钉和 j (0 <= j <= n - 2 - i)个不与之相邻的红钉。
现在考虑一下最后取的那个红钉有多少种选法。对于每种连续的 i 个红钉,两侧各自的 i - t 个红钉不能最后选择,否则一定在选这些红钉之前就选够了连续的 t 个红钉。则对于每种连续的 i 个红钉,最后取的那个红钉有 i - 2 * ( i - t ) = 2 * t - i 种选法。
对于剩下的 i + j - 1 个要选的红钉,顺序无所谓,故乘以 ( i + j - 1)的阶乘。
再来考虑对于 i 和 j 的组合有多少种选法,对于既定位置的 i 个连续红钉,易知有种 j 的选法。
对于n边形,显然有n种不同的选择连续 i 个红钉的选法。因此总的选法数目要在上述基础上乘以 n。
考虑n为偶数的情况:
显然只比奇数情况多了选 n - 1个红钉的选法,易知有n * ( n - 2 ) ! 种选法。
于是得出公式
时间复杂度可视为O(n^2) 。
代码:
- #include<bits/stdc++.h>
- using namespace std;
- #define fer(i,a,b) for(int i=a;i<=b;i++)
- #define fdr(i,a,b) for(int i=a;i>=b;i--)
- #define int long long
- #define endl '\n'
- #define ll long long
- const int N=5000+100;
- int gcd(int x,int y){if(y==0) return x;else return gcd(y,x%y);}
- int n,mod;
- int c[N][N];
- int fac[N];
- signed main()
- {
- ios::sync_with_stdio(0);cin.tie(0),cout.tie(0);
- cin>>n>>mod;
- fer(i,0,N-1) c[i][0]=1;
- fer(i,1,N-1){
- c[i][i]=1;
- fer(j,i+1,N-1){
- c[j][i]=(c[j-1][i]+c[j-1][i-1])%mod;
- }
- }
- fac[0]=fac[1]=1;
- fer(i,2,N-1) fac[i]=fac[i-1]*i%mod;
- int ans=0,t=n/2;
- fer(i,t,n-1){
- if((n&1)&&i==n-1) break;
- int k=n-i-2;
- if(i==n-1) k=0;
- fer(j,0,k) ans=(ans+n*(2*t-i)*fac[i+j-1]%mod*c[k][j]%mod)%mod;
- }
- cout<<ans<<endl;
- }
E.Doremy's Number Line
思路引用自Codeforces Global Round 24 A - E - 知乎
先进行特判:
(1)a1>=k一定有解
(2)a1+b1<k一定没有解
(3)n=1且不满足(1)的话也一定没有解
然后对2~n的a,b数组联合进行以a数组为优先的从小到大排序。用pair存储a数组和b数组,方便直接用sort进行排序。
排完序后,对于2,我们直接取a[2],这是到2时能取的最大值。在3~n中,不断迭代,找能被涂色的最大值mx。
找到最大值mx后,判断min( a[1] , mx ) + b[1] 能否 >= k即可。
在找最大值mx时,有以下几个比较点:
(1)到 i 时当前已确定能取的最大值f [ i - 1]
(2)到 i 时新出现的可取的可能最大值,min( f [ i - 1 ],a[ i ] ) + b[ i ]
(3)取a[ i - 1]+b[ i - 1]
(此种取法是因为排序后a[ i ]>a[ i - 1 ],所以可以先取a[ i ] ,再操作 i - 1,保证没有遗漏 )
(4)直接取a[ i ]
代码:
- #include<bits/stdc++.h>
- using namespace std;
- #define int long long
- #define endl '\n'
- #define fer(i,a,b) for(int i=a;i<=b;i++)
- #define xx first
- #define yy second
- #define P pair<int,int>
- const int N=1e5+10;
- const int INF=1e9+10;
- int n,k;
- int f[N];
- int a[N],b[N];
- P p[N];
- void solve(){
- if(p[1].xx>=k){
- puts("YES");
- return;
- }
- if(n==1){
- puts("NO");
- return;
- }
- if(p[1].xx+p[1].yy<k){
- puts("NO");
- return;
- }
- sort(p+2,p+n+1);
- f[2]=p[2].xx;
- fer(i,3,n){
- f[i]=max(f[i-1],min(f[i-1],p[i].xx)+p[i].yy);
- f[i]=max(f[i],p[i-1].xx+p[i-1].yy);
- f[i]=max(f[i],p[i].xx);
- }
- int res=min(f[n],p[1].xx)+p[1].yy;
- if(res>=k) puts("YES");
- else puts("NO");
- return;
- }
- signed main(){
- ios::sync_with_stdio(0);cin.tie(0),cout.tie(0);
- int t;
- cin>>t;
- while(t--){
- cin>>n>>k;
- fer(i,1,n){
- cin>>a[i]>>b[i];
- p[i].xx=a[i],p[i].yy=b[i];
- }
- solve();
- }
- }