A. Gift Carpet
每道题都是伸缩代码框有ac代码请不要漏掉
--------------------------题解-----------------------------
按先行便然后列再变循环 设置jud每满足一个条件就让jud++ 只有jud==相应值的时候才让其++
点击查看代码
#include<bits/stdc++.h>
using namespace std;
char a[30][30];
int main()
{
int t;
cin>>t;
while(t--)
{
int n,m;
cin>>n>>m;
int jud=0;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
cin>>a[i][j];
}
}
for(int j=1;j<=m;j++)
{
for(int i=1;i<=n;i++)
{
if(jud==0&&a[i][j]=='v')
{
jud++;
break;
}
if(jud==1&&a[i][j]=='i')
{
jud++;
break;
}
if(jud==2&&a[i][j]=='k')
{
jud++;
break;
}
if(jud==3&&a[i][j]=='a')
{
jud++;
break;
}
}
}
if(jud==4) cout<<"YES"<<'\n';
else cout<<"NO"<<'\n';
}
}
B. Sequence Game
这题题意比较难理解,总的来说就是B的数列是A中 a[i]>=a[i-1]的数据现在让你根据B数列构造一个可能的A数列出来
--------------------------题解-----------------------------------------
经过长时间观察后我得出,只需要遍历B数列,如果看到一个b[i]<b[i-1]就说明原数列在这个地方不符合a[i]>=a[i-1]的要求,因此我们按照以下方法构造
b[i]>=b[i-1]则照抄b数列,不符合该要求时便多构造一个b[i-1]使他在原数列中符合要求 按照我的方法模拟一遍然后你输出构造的数列你就差不多懂了
可以在根据 (a[i]>=a[i-1]便放进b数列中这个要求检验一下看看是不是原先的B数列)
点击查看代码
#include<bits/stdc++.h>
using namespace std;
const int N=4e5+10;
int a[N];
int b[N];
int main()
{
int t;
cin>>t;
while(t--)
{
int n;
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i];
int cnt=1;
b[1]=a[1];
for(int i=2;i<=n;i++)
{
if(a[i]<a[i-1])
{
cnt++;
b[cnt]= a[i];
}
cnt++;
b[cnt]=a[i];
}
cout<<cnt<<'\n';
for(int i=1;i<=cnt;i++)
{
cout<<b[i]<<" ";
}
cout<<'\n';
}
}
C. Flower City Fence
这题题意更是重量级的难懂,我大概概括一下,先给你一个如图一样排列的阶梯,然后你把这个阶梯按题目要求翻转(大的在下小的在上)然后再把翻转后的台阶看成一个全新的台阶,重新划分第1,2,3...阶梯把他们的高度统计出来,看他们的高度是否与未翻转的台阶相同(结合图理解)
---------------------------------------------------题解-------------------------------------------
首先我们要先记住题目给你的台阶一定是非递增数列也就是a[i+1]<=a[i] 加入有5个台阶 高度为6 6 6 6 6 把他们横过来之后 他们就会变成 5 5 5 5 5 5不符合要求由此我们可以看出每个台阶的高度都会对翻转
后的台阶高度做出一定贡献(也可能不做主要是看他翻转前的高度) 高度为x便可以对翻转后高度1~x的阶梯高度有1的贡献,所以我们可以得出一个结论 如果最大的a[1]>n的时候,该阶梯翻转之后是必然不可能和之前一样
的 比如n=1 a1=6 翻转后会变成 1 1 1 1 1 1.理解这块后就好做了我们枚举每一个点判断翻转后本应该最后对这个点做出贡献的x柱子(由于单调递减只要他做出了贡献他前面的也做出了贡献)有没有做到贡献以及x+1
个柱子是不是没有做到贡献(没有做到就对了) 可能比较难理解,建议反复读题和观看代码
点击查看代码
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N=2e5+10;
int a[N];
signed main()
{
int t;
cin>>t;
while(t--)
{
int n;
cin>>n;
int jud=0;
for(int i=1;i<=n;i++) cin>>a[i];![](/i/l/?n=24&i=blog/3418807/202407/3418807-20240701085937602-1590934993.png)
if(a[1]>n) jud=1;
a[n+1]=0;a[0]=0;
if(jud==0){//这个if也要注意不然会数组越界,此题有更简单和暴力的办法,但我赛中只想到了这个
for(int i=1;i<=n;i++)
{
if(a[a[i]]<i||a[a[i]+1]>=i) jud=1;//判断翻转后该位置柱子是否准确的被翻转前的柱子做到了贡献
}
}
if(jud==1) cout<<"NO"<<'\n';
else cout<<"YES"<<'\n';
}
}
D. Ice Cream Balls
我不擅长的数学题,但总体难度不难主要考察二分,能看到这里的想必都是高手了,我会说的简单一点主要,分享一下我的推导思路
--------------------------------题解--------------------------------------
由题意我们知道这里面有一个数论原理,我简单解释一下,比如我们要凑出6种双球(以下统称sq单球统称dq),答案是 4
我们这么看第一个球可以和第2 3 4 个凑
第二个可以和3 4个凑
第三个可以和第4个凑
第4个没得凑
我们便可以列出这样的公式
x-1
+
x-2
+
x-3
+
x-4
=n
此时x为4 n=6便是正确答案
把这几个公式加起来可以简化成x*(x-1)/2==n
我们利用这个公式便可以进行二分
这是这题的第一个关键点
题目中说了需要正好能凑出n种双球我们拿n=179举例 这个样例你按照我的公式二分之后 l=19,我们是二分出来按照公式后得出来的最大但是绝对不超过n的一个数字便是19
然后19能正好凑出171种 但题目问的是需要几个球,因此可以买重复的凑成类似(1,1)(2,2)的sq 所以我们要在19的基础上再重复买(179-171)种球 19+8加起来便是27个与题目一答案一样
二分出来的并不是直接答案
这是第二个关键点
点击查看代码
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll n;
ll check(ll q)
{
//if(q*q-((1+q)*(q/2))==n) return 3;
if(q*(q-1)/2>n) return 1;
else return 0;
}
int main()
{
ll t;
cin>>t;
while(t--)
{
cin>>n;
if(n==1) cout<<2<<endl;
else{
// x*x-1+x=n
ll l=1,r=3e9;
while(l<r)
{ // cout<<l<<endl;
ll mid=(l+r+1)/2;
// cout<<mid<<endl;
if(check(mid)==0) l=mid;
else r=mid-1;
}
// cout<<l<<'\n';
ll sum=0;
sum=l*(l-1)/2;
//cout<<sum<<endl;
//sum=sum-(l-1);
cout<<l+(n-sum)<<'\n';
}
}
}
E. Kolya and Movie Theatre
能看到这里的也是高手了,我就不赘述了,说得简单一点,这道题赛中时间不够了不然我就上大分了
这题总体不难主要考察数据结构和枚举,我们要枚举每一个 a[i]作为最后一个点(这里会影响减去了多少个d)同时维护一个最大值,同时开一个优先队列(小的在前)用来维护所选的m个是否需要去掉,不论我们怎选所消耗掉的dcnt都只和最后一个点有关所以我们不用考虑太多,每次减少的cntd恒等于d*i,因此我们只需要关心a[i]本身的大小就好..队列内部元素数量不足m时候主要是正数就入队切加入sum,队列元素>=m时候就判断是否需要把最小的移除
点击查看代码
#include<bits/stdc++.h>
using namespace std;
const int N=2e5+10;
typedef long long ll;
ll a[N];
int main()
{
int t;
cin>>t;
while(t--)
{
ll n,m,d;
cin>>n>>m>>d;
for(ll i=1;i<=n;i++) cin>>a[i];
priority_queue <int,vector<int>,greater<int> >q;
ll sum=0;
ll ans=0;
ll cnt=1;
ll nl=0;
for(ll i=1;i<=n;i++)
{ sum-=d;
ll q1=q.size();
if(q1<m)
{
if(a[i]>0) sum+=a[i],q.push(a[i]);
// cout<<sum<<endl;
}
else
{
ll num1=q.top();
if(num1<a[i])
{
sum=sum-num1+a[i];
q.pop();
q.push(a[i]);
}
}
// cout<<sum<<" "<<a[i]<<endl;
ans=max(ans,sum);
}
cout<<ans<<'\n';
}
}
/*
1
2 1 1
-1 2
*/
请各位看了之后大胆评论说一下感受,会根据各位的感受调整
标签:894,数列,jud,int,ll,cin,Codeforces,cd,翻转 From: https://www.cnblogs.com/qau-marisa3/p/18277395