A题:
You are given an integer n. Check if n has an odd divisor, greater than one (does there exist such a number x (x>1) that n is divisible by x and x is odd).
For example, if n=6, then there is x=3. If n=4, then such a number does not exist.
解题思路:一个数字如果是2的n次方的话就不能被奇数整除,反之则能被奇数整除。先判断一个数是不是偶数,如果是的话将一个数不断的除2,能被2除尽,那么就打印NO。反之则打印YES
如8,8%20,8/=2,4/2=2,2/=2,最后是1,打印NO。10,10%20,10/=2,5%2!=0. 5!=1,打印YES.
#include
#define ll long long
int main()
{
ll n,t;
while(~scanf("%lld",&t))
{
while(t--){
scanf("%lld",&n);
while(n%2==0)n/=2;
if(n==1)printf("NO\n");
else printf("YES\n");
}
}
return 0;
}
B题:
Polycarp remembered the 2020-th year, and he is happy with the arrival of the new 2021-th year. To remember such a wonderful moment, Polycarp wants to represent the number n as the sum of a certain number of 2020 and a certain number of 2021.
For example, if:
n=4041, then the number n can be represented as the sum 2020+2021;
n=4042, then the number n can be represented as the sum 2021+2021;
n=8081, then the number n can be represented as the sum 2020+2020+2020+2021;
n=8079, then the number n cannot be represented as the sum of the numbers 2020 and 2021.
Help Polycarp to find out whether the number n can be represented as the sum of a certain number of numbers 2020 and a certain number of numbers 2021.
解题思路:水题一道,直接上代码
#include
int main()
{
int t;
scanf("%d",&t);
while(t--){
int a,b,n;
scanf("%d",&n);
a=n/2020;
b=n%2020;
if(a<b) printf("NO\n");
else printf("YES\n");
}
return 0;
}
C题:
You have an array a1,a2,…,an. All ai are positive integers.
In one step you can choose three distinct indices i, j, and k (i≠j; i≠k; j≠k) and assign the sum of aj and ak to ai, i. e. make ai=aj+ak.
Can you make all ai lower or equal to d using the operation above any number of times (possibly, zero)?
解题思路:
分两种情况:1.全部数字都小于d。
2.最小两个数字小于d。
那么就要找出两个最小值min1,min2;
方法1:冒泡排序,但是有可能超限。
方法2:线性查找,如下:
#include
int main()
{
int t;
while(~scanf("%d",&t))
{
while(t--){
int min1,min2,k,imin1,i,n,d,a[300];
scanf("%d%d",&n,&d);
k=1;
for(i=0;i<n;i++){
scanf("%d",&a[i]);
if(i==0){
min1=a[0];imin1=0;}
if(min1>a[i]){
min1=a[i];imin1=i;
}
if(a[i]>d){
k=0;
}
}
if(k){
printf("YES\n");continue;
}
if(imin1==0)min2=a[1];
else min2=a[0];
for(i=0;i<n;i++){
if(i!=imin1){
if(min2>a[i]){
min2=a[i];
}
}
}
if(min1+min2<=d)printf("YES\n");
else printf("NO\n");
}
}
return 0;
}
D题:网上有答案,答案如下:
#include
#include
#include
#include
using namespace std;
typedef long long ll;
const int maxn = 2e5 + 7;
const int INF = 0x3f3f3f3f;
char s[maxn],t[maxn];
int len1,len2;
bool check1(int x,int len,char *s) {
if(len % x != 0) return false;
for(int i = 0;i < len;i++) {
if(s[i] != s[i % x]) return false;
}
return true;
}
bool check3(int x,int y) {
if(x != y) return false;
for(int i = 0;i < x;i++) {
if(s[i] != t[i]) return false;
}
return true;
}
int gcd(int n,int m) {
return m == 0 ? n : gcd(m,n % m);
}
int main() {
int T;scanf("%d",&T);
while(T--) {
scanf("%s%s",s,t);
len1 = strlen(s),len2 = strlen(t);
int l1 = len1,l2 = len2;
//找s字符串的最小循环节
for(int i = 1;i <= len1;i++) {
if(check1(i,len1,s)) {
l1 = i;break;
}
}
//找t字符串的最小循环节
for(int i = 1;i <= len2;i++) {
if(check1(i,len2,t)) {
l2 = i;break;
}
}
//如果这俩字符串的最小循环节不一样
//就打印-1
if(check3(l1,l2)==0) {
printf("-1\n");
}//如果一样就找出他们的最小公倍数
else {
len1 /= l1;
len2 /= l2;
int lcm = len1 * len2 / gcd(len1,len2);
for(int i = 0;i < lcm;i++) {
for(int j = 0;j < l1;j++) {
printf("%c",s[j]);
}
}
printf("\n");
}
}
return 0;
}