Codeforces Round891(Div3)

说在前面的话:

心血来潮想要补一场Div3,这些题目确实很有意思。英文题面真的难懂,但是洛谷上的简洁题面无疑降低了难度。

然后通过这次补题经历,更加感到了不开long long见祖宗,所以,读者可以发现有几道题用了signed(源代码已经改成这样力,不想被long long再搞一次了)。

最后,碍于DevC++的功能有限,不能像VS Code等软件那样直接在界面进行类似文件读入输出的操作,使得界面十分清晰,所以还用什么DevC++个人认为文件读入输出操作更能辨别正确与否。

A

就是给出一个数组,将数组元素染上两种不同的颜色,判断是否存在某种染色方案,使得每种颜色的数字之和的奇偶性相同。

当然有结论:数字之和为偶数即可。不证。
我当时觉得把奇数偶数配对,这样一层一层算下去直到一方为0。属于瞎做做法(。

#include <bits/stdc++.h>
#define ll long long
#define re register
using namespace std;
const int N=100, INF=0x3f3f3f3f;
int T,n,a[N];
int ou,ji;
void f(int x,int y){
while(x!=0&&y!=0){
int k=min(x,y);
y-=k;
}
if(x==0)puts("YES");
else{
if(x%2==0)puts("YES");
else puts("NO");
}
}
int main(){
/*freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);*/
cin>>T;
while(T--){
cin>>n;
ou=0;ji=0;
for(int i=1;i<=n;i++){
cin>>a[i];
if(a[i]%2==0)ou++;
else ji++;
}
f(ji,ou);
}
return 0;
}

B

B就是将一个数字进行若干次(或不进行)五入的进位操作,求可得到的最大值。

很明显贪心,我们从右往左遍历,能进位就进位,记得处理一下9进位即可。

#include <bits/stdc++.h>
#define ll long long
#define re register
using namespace std;
const int N=800, INF=0x3f3f3f3f;
string s;
int T;
int main(){
/*freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);*/
cin>>T;
while(T--){
cin>>s;s='0'+s;
int num=s.size();
for(int i=s.size()-1;i>0;i--){
if(s[i]=='9'+1){
s[i]='0';
s[i-1]++;
}
if(s[i]>='5'){
num=i;
s[i-1]++;
}
}
for(int i=0;i<s.size();i++){
if(i==0&&s[i]=='0')continue;
if(i<num)cout<<s[i];
else cout<<0;
}
cout<<endl;
}
return 0;
}

C

构造题,题面很清楚了已经。

因为对于一个非下降数列a1,a2,...,ana1要和n1个数比较,所以也会有n1a1出现在B中,后面以此类推。

#include <bits/stdc++.h>
#define ll long long
#define re register
using namespace std;
const int N=1e6+5, INF=0x3f3f3f3f;
int T,n,a[N],b[N];
int main(){
/*freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);*/
cin>>T;
while(T--){
cin>>n;
ll bn=n*(n-1)/2;
for(int i=1;i<=bn;i++)cin>>b[i];
sort(b+1,b+bn+1);
int i=1,j=n-1;
while(i<=bn){
cout<<b[i]<<' ';
i+=j;
j--;
}
cout<<b[bn]<<endl;
}
return 0;
}

D

题面更是清晰,洛谷上一概括确实好受不少(

一眼图论题,再一眼傻瓜题,如果按题目来做就是O(n2),肯定超时,那我们就略微移项:

auavbubvaubuavbv

所以只需要求出最大差值,然后看看有几个和最大值一样的值就行了。

#include <bits/stdc++.h>
#define ll long long
#define re register
using namespace std;
const int N=2e5+5, INF=0x3f3f3f3f;
int T,n,a[N],b[N],maxn;
int main(){
/*freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);*/
cin>>T;
while(T--){
cin>>n;
maxn=-2e9;//这里注意,每个元素是[-1e9,1e9],这个最小有-2e9(错了好几次
for(int i=1;i<=n;i++)cin>>a[i];
for(int i=1;i<=n;i++){
cin>>b[i];
maxn=max(maxn,a[i]-b[i]);
}
int t=0;
vector<int> S;
for(int i=1;i<=n;i++)if(a[i]-b[i]==maxn){t++;S.push_back(i);}
cout<<t<<endl;
for(auto i:S)cout<<i<<' ';
cout<<endl;
}
return 0;
}

E

题目就是有n个点,放在数轴上面,对于其中一个数,计算它与其余各点(包括自身)之间点的个数之和。

一眼DP,但是后面没写成DP。这题只要愿意算,基本没啥问题(推的式子都没我以前写的几道复杂,而且也不用证明),单纯模拟即可:
我们记sk表示第k个数的按题目所求的值。

sk=Σi=1k(akai+1)+Σi=k+1n(aiak+1)

=kakΣi=1kai+k+Σi=k+1nai(nk)ak+(nk)

=(2kn)ak+n+Σi=k+1naiΣi=1kai

前面三项我们可以直接算,后面两个可以用后缀和以及前缀和做。
(可以看出,这题被long long背刺了)

#include <bits/stdc++.h>
#define ll long long
#define int long long
#define re register
using namespace std;
const int N=2e5+5, INF=0x3f3f3f3f;
int T,n,a[N],b[N];
ll pre[N],suf[N];
map<int,ll>ans;
signed main(){
/*freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);*/
cin>>T;
while(T--){
cin>>n;
memset(pre,0,sizeof(pre));
memset(suf,0,sizeof(suf));//多测记得清空
for(int i=1;i<=n;i++)cin>>a[i],b[i]=a[i];
sort(a+1,a+n+1);
for(int i=1;i<=n;i++)pre[i]=pre[i-1]+a[i];//前缀和
for(int i=n-1;i>=1;i--)suf[i]=suf[i+1]+a[i+1];//后缀和
for(int i=1;i<=n;i++)ans[a[i]]=(2*i-n)*a[i]+n+suf[i]-pre[i];//套公式
for(int i=1;i<=n;i++)cout<<ans[b[i]]<<' ';
cout<<endl;
}
return 0;
}

F

题面

一眼梦回2022CSP-J,我们只需运用初中数学一元二次方程即可。
对于题中两个式子移项合并可得:

ai2xai+y=0

ai可以换成aj,二者为方程x2bx+c=0的二根。

ai=x±x24y2

注意一下Δ非负且能开尽,上面是偶数就行了。如果两根相同,那么ans=Ck2=k(k1)2k就是值为ai的数的个数,组合公式算得。如果两根不同,根据乘法定理,ans=k1k2
(再次被long long薄纱)

#include <bits/stdc++.h>
#define int long long
#define re register
using namespace std;
const int N=2e5+5, INF=0x3f3f3f3f;
map<int,int>check;
bool pd(int n){
int k=sqrt(n);
return k*k==n;
}
int delta(int x,int y){
int k=x*x-4*y;
if(k<0||!pd(k))return -1;
return sqrt(k);
}
int T,n,a[N],q;
signed main(){
/*freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);*/
cin>>T;
while(T--){
cin>>n;
check.clear();
for(int i=1;i<=n;i++){cin>>a[i];check[a[i]]++;}
cin>>q;
while(q--){
int ans=0;
int x,y;cin>>x>>y;
int del=delta(x,y);
if(del==-1||(x+del)%2!=0){
cout<<0<<' ';continue;
}
int N_x1=check[(x+del)/2],N_x2=check[(x-del)/2];
if((x+del)/2==(x-del)/2)ans=N_x1*(N_x1-1)/2;
else ans=N_x1*N_x2;
cout<<ans<<' ';
}
cout<<endl;
}
return 0;
}

G

emm不会,这个真是图论了。以后会了再补。

posted @   LsmQwQ  阅读(46)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 因为Apifox不支持离线,我果断选择了Apipost!
· 通过 API 将Deepseek响应流式内容输出到前端
点击右上角即可分享
微信分享提示