Cf #818 Div.2
文章目录
A. Madoka and Strange Thoughts
-
题意
- 问1~n中有多少对(a,b)满足lcm(a,b)<=3*gcd(a,b)
-
题解
-
已知lcm(a,b)=a*b/gcd(a,b),所以原式可以化为,并且只有如下几种情况符合要求,下列式子中认为a,b等价,但是题目中非等价,简写
a × b g c d 2 ( a , b ) < = 3 设 g c d ( a , b ) = t ; 1. a = b = t 2. a = t , b = 2 t 3. a = t , b = 3 t \frac{a\times b}{gcd^2(a,b)}<=3\\ 设gcd(a,b)=t;\\ 1.a=b=t\\ 2.a=t,b=2t\\ 3.a=t,b=3t gcd2(a,b)a×b<=3设gcd(a,b)=t;1.a=b=t2.a=t,b=2t3.a=t,b=3t -
因此1~n中,有n对a=b的,有n/2对a=t,b=2t的,有n/3对a=t,b=2t的。同时a,b位置可以互换
-
-
代码
#include <iostream>
using namespace std;
int n;
void solve() {
cin>>n;
cout<<n+(n/2+n/3)*2<<'\n';
}
int main() {
int t;
cin>>t;
while(t--) solve();
return 0;
}
B. Meeting on the Line
-
题意
- 有n阶的棋盘,n为k的倍数,构造一个每k个行或者列的格子都至少有一个’X’的其他都为’.‘的棋盘。给定一个位置(r,c)放置’X’,输出一个’X’最少的棋盘情况
-
题解
- 棋盘放的最少的个数是确定的,每一行都需要放置n/k个’X’,所以总共要放置n*n/k个’X’
- 对于一个k*k的小棋盘,在副对角线上放置’X’为一种构造方式,放在副对角线还有一个好处,就是副对角线上的横纵坐标之和恒定,方便计算和构造
- 对于n*n的棋盘,在给定点所在的副对角线放上’X’之后,还需要上下左右平移k个位置后得到的对角线放上’X’,即对所有的坐标(i,j)若满足**(i+j)%k==(r+c)%k**则放置’X’,否则放置’.',易证得其位置一定符合要求且’X’数量为最小
-
代码
#include <iostream>
#include <cmath>
using namespace std;
void solve() {
int n,k,r,c;
cin>>n>>k>>r>>c;
for(int i=1;i<=n;i++) {
for(int j=1;j<=n;j++) {
if(abs(i+j-r-c)%k==0) cout<<'X';
else cout<<'.';
}
puts("");
}
}
int main() {
int t;
cin>>t;
while(t--) solve();
return 0;
}
C. Madoka and Formal Statement
-
题意
- 给定两个长度为n的数组a,b,经过若干操作,问能否将a变成b
- 操作:若a[i]<=a[(i+1)%n],则a[i]++
-
题解
- 对于a[i]!=b[i]时,若a[i]>b[i],则不可能完成变换;若a[i]<b[i],要将a[i]变成b[i],需要保证b[i+1]+1>=b[i],因为一定能找到一种贪心方法,将a[i+1]变成b[i]-1
-
代码
#include <iostream>
using namespace std;
const int N=2e5+10;
int n,a[N],b[N];
void solve() {
cin>>n;
for(int i=0;i<n;i++) cin>>a[i];
for(int i=0;i<n;i++) cin>>b[i];
for(int i=0;i<n;i++)
//不合法的情况
if( a[i]>b[i] || (a[i]!=b[i] && b[i]>b[(i+1)%n]+1) ) {
puts("NO");
return ;
}
puts("YES");
}
int main() {
int t;
cin>>t;
while(t--) solve();
return 0;
}