Codeforces Round #720 ( Div 2) ABC 题解(c++实现)

靓仔的第一篇博客。

本人ACM菜鸟+新手,因此这篇博客更多的是作为笔记的作用,记录一下自己打训练来的成果和心路历程(其实是和鸟宝吹水说要写博客)。

以后不知道还会不会写(懒

---------------------------------------------------------------------------------------------------

A. Nastia and Nearly Good Numbers

链接:Problem - A - Codeforces

题意: 大概就是给你两个数A和B, 要求你输出3个数 X,Y,Z(输出之前要先输出YES)。 其中X+Y=Z,并且X和Y可以被A整除(称之为nearly good 的数),Z可以被A*B整除(称之为good 的数)。

如果找不到X、Y、Z,就输出 NO。

输入范围: 1< = A,B<= 1e6

输出范围: 1<=X,Y,Z<=1e18

注意:题目中的X和Y(nearly good) 只要被A整除就可以,被B整除也可以。(最开始我理解错题意,将A==B视为错误的情况,WA了11次.............)。

根据题意输入A和B,我们可以直接输出 A*(B-1)、A*(B+1)和 2 *A*B 就可以了。

由题目的输出限制条件可以知道,如果B等于1,那么会输出0,不符合题意,因此B==1就是错误条件。

代码如下:

#include<bits/stdc++.h> 
#define endl '\n'
#define ll long long
using namespace std;
int main(){
    ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
    int t;cin>>t;
    while(t--){
    	ll a,b;cin>>a>>b;
    	if(b==1){
    		cout<<"NO"<<endl;
    		continue;
		}
		cout<<"YES"<<endl;
		cout<<a*(b-1)<<' '<<a*(b+1)<<' '<<2*a*b<<endl;
    }
}

---------------------------------------------------------------------------------------------------

B. Nastia and a Good Array

链接:Problem - B - Codeforces

题意:给你N个数组成的数组,要求你最终通过变换,让这个数组最终每个相邻的数之间的最大公约数为1,即gcd(ai,aj)= 1  ,其中 | i - j | =1。

变换的规则:选定2个数,ai和aj,1<=i,j<=N,可以将ai和aj变更为任意的x和y,只要保证min(ai,aj)= min(x ,y) ,也就是改变这两个数时只要保证其中最小的数字不改变就可以了。

输入:T,表示有T组样例,然后是N和N个数字。1<= ai <= 1e9 (1<=i<=N)。

输出:输出操作次数num,接下来的num行,每行输出四个数,分别是 i ,j,x,y,也就是你要变换的两个数在数组中的下标以及变换后的数字x和y。

解题思路: 最开始我想的很复杂,但是听了鸟宝的思路后发现有一种更简单的写法(鸟宝,我的鸟宝)。

举个栗子: 数组  9 、6、3、11、15。根据变换的规则要求最小的数字不变,我可以将数组变成这样:3、4、3、4、3。  这样就保证了每两个相邻的数字之间是互质的,并且操作次数可以稳定在N-1次。

非常巧妙和聪明的写法,这样写可以保证每次输出时间复杂度控制在O(n),我只要找到最小的数的下标,然后从这个数到下标为1的数,每次交替输出min+1,min和min,min就可以了。同理,在从最小的数到下标为N的数,每次交替输出min,min+1和min,min。(可能有更好的解法,不过这个简单。)

代码如下:

#include<bits/stdc++.h> 
#define endl '\n'
#define ll long long
using namespace std;
int main(){
    ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
    int t;cin>>t;
    while(t--){
    	int n;cin>>n;
    	ll minn= 0x7f7f7f7f;
		int note=1;
    	ll tmp=0;
    	for(int i=1;i<=n;i++){
		    cin>>tmp;
    		if(tmp<minn){
    			minn=tmp;
    			note=i;
			}
		}
    	cout<<n-1<<endl;
    	int check=1;
    	// 输出前面的 
    	// check用来交替输出 x和y  
    	for(int i=note-1;i>=1;i--){
    		cout<<i<<' '<<note<<' ';
    		if(check%2==0)cout<<minn<<' '<<minn<<endl,check++;
    		else cout<<minn+1<<' '<<minn<<endl,check++;
		}
		// 输出后面的 
		check=1;
    	for(int i=note+1;i<=n;i++){
    		cout<<note<<' '<<i<<' ';
    		if(check%2==0)cout<<minn<<' '<<minn<<endl,check++;
    		else cout<<minn<<' '<<minn+1<<endl,check++;
		}
	}
}

---------------------------------------------------------------------------------------------------

C. Nastia and a Hidden Permutation

链接:Problem - C - Codeforces

大意:这是一道交互题,类似于你给电脑提问,电脑给你回答,你根据回答来判断出答案这种(不太严谨的描述)。

我也是第一次做这种题目,一开始连题意都没看懂,后面去看了别的大佬的题解才搞懂了这道题。

要注意的是,题目要求使用 fflush(stdout) or cout.flush() 来刷新缓存区以免输出出现问题,这里也可以使用 cin.ignore()来达到同样的效果。

这题确实超出了我的能力范围,因此这里就不描述题意和解释了,直接放出大佬题解的链接来吧。

大佬的题解:(27条消息) Codeforces #720 div2 A~E题解_月阁-CSDN博客 

AC代码:

#include<bits/stdc++.h> 
#define endl '\n'
#define ull unsigned long long 
using namespace std;
const int N=1e4+7;
int n,ar[N];
int ask(int i,int j,int t,int x){
	cout<<"?"<<' '<<t<<' '<<i<<' '<<j<<' '<<x<<endl;
	int ans;cin>>ans;
	return ans;
}
void solve(){
	cin>>n;
	int note=-1;
	for(int i=1;i<=n;i+=2){
		int j=i%n+1;
		int ans=ask(i,j,1,n-1);
		if(ans==n){
			note=j;break;
		}
		else if(ans==n-1){
			if(ask(j,i,1,n-1)==n){
				note=i;break;
			}
		}
	}
	for(int i=1;i<=n;i++){
		if(i==note){
			ar[i]=n;
			continue;
		}
		int ans=ask(i,note,2,1);
		ar[i]=ans;
	}
	cout<<"!"<<' ';
	for(int i=1;i<=n;i++){
		cout<<ar[i]<<' ';
	}
	cout<<endl;
}
int main(){
    int t;cin>>t;
    cout.flush(); //此处也可以为 cin.ignore(); 
    while(t--){
    	solve();
    	cout.flush();
	}
}

---------------------------------------------------------------------------------------------------

第一次写博客,也不知道链接可不可以用,不能用也无所谓了。

 

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值