很久没打cf了 被以前经常A不出题支配了 距离上次比赛 大概一个多月了 想着看看这段时间能力提升如何
A题 给你一个数组 可以实现ai 和aj 把aj值赋给ai 问你能不能使得该数组之和是奇数
分析:如下思考 先记录前缀和 和奇数的个数 如果前缀和是偶数并且奇数个数=n那么肯定n是偶数 既然如此ai aj不论怎么赋值 都是奇数 不影响 所以一定会被2整除 NO构造不出 另一种情况就是奇数个数为0 也不可以构造出来 其余的yes
A
//
int main()
{
ll p=read();
while(p--){
ll n=read();
ll ans=0,cnt=0;
for(int i=0;i<n;i++){
ll x=read();
if(x&1) cnt++;
ans+=x;
}
if(ans%2==0&&cnt==n) printf("NO\n");
else if(cnt==0) printf("NO\n");
else printf("YES\n");
}
return 0;
}
B题意 比如给你n元去买物品 花费了x元 那么会退回我们 ⌊x/10⌋ 问我们用n元买东西 最多可以买多少钱的货
题解 模拟一下即可
B题目链接
#include<bits/stdc++.h>
#define ll long long
#define inf 0x3f3f3f3f
#define mod 1000000007
#define PI acos(-1)
#define fi first
#define se second
#define lowbit(x) (x&(-x))
#define mp make_pair
#define pb push_back
#define si size()
#define E exp(1.0)
#define fixed cout.setf(ios::fixed)
#define fixeds(x) setprecision(x)
#define IOS ios::sync_with_stdio(false);cin.tie(0)
using namespace std;
inline ll read(){
char c=getchar();
ll f=1,x=0;
while(c<'0'||c>'9'){
if(c=='-')
f=-1;
c=getchar();
}
while(c>='0'&&c<='9'){
x=(x<<1)+(x<<3)+(c^'0');
c=getchar();
}
return x*f;
}
int main()
{
ll p=read();
while(p--){
ll n=read();
ll x=round(n/10);
ll y=round((n+x)/10);
ll ans=0;
while(y>x){
x=y;
y=round((n+x)/10);
}
printf("%lld\n",n+y);
}
return 0;
}
C题 题意是什么呢? 就一个机器人的行走路线告诉了我们 询问我们最小的一个区间[l,r] 这一段区间结束的时候 机器人返回了之前经过的位置 问[l,r] 无就输出-1
题解:stl 中map的运用 标记坐标和经过的次数
C链接
int main()
{
ll p=read();
while(p--){
ll n=read();
string s;
cin>> s;
ll d=inf;
ll x=0,y=0,l=-1,r=-1;
map<pair<ll,ll>,ll>mp;
mp[{0,0}]=0;
for(int i=0;i<n;i++){
if(s[i]=='L')
x++;
if(s[i]=='R')
x--;
if(s[i]=='U')
y++;
if(s[i]=='D')
y--;
if(mp.count({x,y})!=0){
if( (i+1-mp[{x,y}]+1) <d){
d=i+1-mp[{x,y}]+1;
l=mp[{x,y}]+1,r=i+1;
}
}
mp[{x,y}]=i+1;
}
if(l==-1||r==-1) printf("-1\n");
else cout<<l<<" "<<r<<endl;
}
return 0;
}
D 有点意思的sort题
题意 假设ysk和yyb两人合伙打怪 一人砍一刀 固定伤害hurt-ysk hurt-yyb
并且如果怪物是ysk干掉的 积分+1 如果怪物是yyb干掉的 不加积分 而且ysk拥有k次鸡会迫使本轮yyb不砍怪 自己去砍怪
问我们两人最多能获取到积分 (我瞎编的,理解下意思就OK)
分析:对于每个怪物 都有固定的位置不可改变(但是我直接对怪物初始hp sort了一下 也AC了 后来发现这个顺序其实并不影响) 还有hp 当然我们不可能真就一刀一刀去模拟,对怪物血量模拟下最终状态 hp=hp%(hurt-ysk + hurt-yyb) 就可以知道最后一刀的归属是谁的(不使用k的鸡会) hp的预处理涉及到分类讨论 hp<=a 那么我们直接总积分++ 如果hp预处理后是0 说明此怪物必当被yyb干掉了 那么直接处理hp=(hurt-ysk + hurt-yyb)(没使用k)那么为了获得到此怪的积分 ysk必须使用一次k 给另外一个数组 存储需要使用迫使操作的次数 全部怪物预处理完了后 对使用迫使鸡会的数组sort一下 从小往大取 直到>=k 此法最贪
//
#include<bits/stdc++.h>
#include<cmath>
#include<string.h>
#include<streambuf>
#include<algorithm>
#define IOS ios::sync_with_stdio(false);cin.tie(0)
#define ll unsigned long long
#define inf 0x3f3f3f3f
#define mea (memset(a,0,sizeof(a)))
#define myit set<ll>::iterator
using namespace std;
inline const int read()
{
int x = 0, f = 1; char ch = getchar();
while (ch < '0' || ch > '9') { if (ch == '-') f = -1; ch = getchar(); }
while (ch >= '0' && ch <= '9') { x = (x << 3) + (x << 1) + ch - '0'; ch = getchar(); }
return x * f;
}//快读
int num[200009],e=0,add2=0,y=0;
const int manx=1e5+5;
int main()
{int sum[200009],n,i,a,b,k,add=0,r,change=0;
cin>>n>>a>>b>>k;
for(i=0;i<n;i++){
cin>>sum[i];
}
sort(sum,sum+n);
for(i=0;i<n;i++){
r=sum[i]%(a+b);//砍
if(r==0){r=a+b;}
if(r<=a){add++;continue;}
if(r-a>0){
//一刀砍不死 a砍不死 b一定坎德斯
r=r-a;
if(r%a==0){
num[e]=r/a;}
else{
num[e]=r/a+1;
}
e++;
}
}
sort(num,num+e);
for(i=0;i<e;i++){
add2=add2+num[i];
if(add2<=k){y++;}
else{break;}
}
printf("%d",add+y);
return 0;
}
E1 E2 其实都要我们找非降序的子序列 只是数据不一样
模拟一下即可
E2
ll a[30];
int main()
{
ll n=read();
string s;
cin>>s;
vector<ll>ans;
ll res=1;
for(int i=0;i<n;i++){
ll d=1;
for(int j=s[i]-'a'+1;j<26;j++)
d=max(d,a[j]+1);
a[s[i]-'a']=d;
ans.push_back(d);
res=max(res,d);
}
cout<<res<<endl;
for(int i=0;i<ans.size();i++)
cout<<ans[i]<<" ";
cout<<endl;
return 0;
}
E1
int main()
{
ll n=read();
string s;
cin>>s;
char c1='a',c2='a';
string ans="";
for(int i=0;i<n;i++){
if(c1<=s[i]){
c1=max(c1,s[i]);
ans+="0";
}
else if(c2<=s[i]){
c2=max(c2,s[i]);
ans+="1";
}
else{
printf("NO\n");
return 0;
}
}
printf("YES\n");
cout<<ans<<endl;
return 0;
}
F LCA
给定一棵n个点的树以及n-1条边,现在给出m组ui,vi,wi,表示ui到vi这条最短路径上的最小边权是wi,要你构造出树的边权。
树上两点的最小边权可以通过lca的方法来遍历求出,关键是怎么构造边权?其实可以把给出的m组条件按从大到小排序,只要保证i点和j点的路径上是权值最大的边先赋值就行。
#include<bits/stdc++.h>
using namespace std;
const int maxn=5e3+1;
const int INF=1e6;
int n,m,num[maxn],size[maxn],ans[maxn],father[maxn],deep[maxn];
struct cxk{
int v,id;
};
struct node{
int u,v,w;
}s[maxn];
vector<cxk>g[maxn];
bool cmp(const node &a,const node &b)
{
return a.w>b.w;
}
void dfs(int u,int fa)
{
father[u]=fa;
deep[u]=deep[fa]+1;
for(auto to:g[u])
{
if(to.v==fa) continue;
dfs(to.v,u);
size[to.v]=to.id;
}
num[u]=INF;
}
bool check(int x,int y,int k)
{
int minn=INF;
if(deep[x]<deep[y]) swap(x,y);
while(deep[x]!=deep[y])
{
if(num[x]==INF) num[x]=k;
minn=min(minn,num[x]);
x=father[x];
}
while(x!=y)
{
if(num[x]==INF) num[x]=k;
minn=min(minn,num[x]);
x=father[x];
if(num[y]==INF) num[y]=k;
minn=min(minn,num[y]);
y=father[y];
}
return minn==k;
}
int main()
{
scanf("%d",&n);
for(int i=1;i<n;++i){
int u,v;
scanf("%d%d",&u,&v);
g[u].push_back({v,i});
g[v].push_back({u,i});
}
dfs(1,0);
scanf("%d",&m);
for(int i=1;i<=m;++i){
int u,v,w;
scanf("%d %d %d",&s[i].u,&s[i].v,&s[i].w);
}
sort(s+1,s+1+m,cmp);
for(int i=1;i<=m;++i){
if(!check(s[i].u,s[i].v,s[i].w)) {
puts("-1");return 0;}
}
for(int i=2;i<=n;++i) ans[size[i]]=num[i];
for(int i=1;i<n;++i) printf("%d ",ans[i]);
}