传送门:A. Olesya and Rodion (水题)
题意:。。。。
思路:刚开始还想用什么字符串模拟或者大数什么的,后来想了想差点笑出声来,样例就是用来忽悠人的。。。
#include <bits/stdc++.h>
#define ll __int64
using namespace std;
const int inf=0x3f3f3f3f;
int n,t;
int main(){
// freopen("in.txt", "r", stdin);
// freopen("out.txt", "w", stdout);
while(~scanf("%d %d",&n,&t)){
if(t==10){
if(n==1)printf("-1\n");
else{
printf("1");n--;
for(int i=1 ; i<=n ; i++)printf("0");
printf("\n");
}
}
else{
for(int i=1 ; i<=n ; i++)printf("%d",t);
printf("\n");
}
}
return 0;
}
传送门:
B. Kolya and Tanya (排列组合)
题意:
在一个圆上,3n个点依次标号,然后标号为i,i+n,i+2n的点连成三角形。然后每个点分配一个值(在1-3范围内)。然后只要有一个
三角形的点的值的和不为6就成功。问有多少种分配方案。
思路
排列组合。总共3^3n个可能,减去7^n个不可能的结果。因为要么是222要么是123才能有6,然后222只有1种123可以6种,加起来一个三角形的不成功的情况有7种。
#include <bits/stdc++.h>
#define ll __int64
using namespace std;
const ll mod=1e9+7;
ll n;
ll pow_mod(ll x, ll n , ll mod){
ll res=1;
while(n>0){
if(n&1)res=res*x%mod;
x=x*x%mod;
n>>=1;
}
return res;
}
int main(){
// freopen("in.txt", "r", stdin);
// freopen("out.txt", "w", stdout);
while(~scanf("%I64d",&n)){
printf("%I64d\n",(pow_mod(27LL,n,mod)-pow_mod(7LL,n,mod)+mod)%mod);
}
return 0;
}
传送门:
C. Marina and Vasya (贪心)
题意
给你两个字符串,要求你构造出第三个字符串,使得第三个字符串和第一个字符串和第二个字符串的不同个数,都是k个
思路:先尽量考虑重叠的情况,然后交替染色就好了
#include <bits/stdc++.h>
#define ll __int64
using namespace std;
const int inf=0x3f3f3f3f;
const int N=1e5+5;
int n,t,cnt=0;
char s1[N],s2[N],s3[N];
bool flag=true,vis[N];
void solve(){
if(cnt==t)return ;
for(int i=0 ; i<n ;i++){
if(s1[i]==s2[i]){
s3[i]=s1[i];
vis[i]=true;
cnt++;
if(cnt==t)return ;
}
}
for(int i=0 ; i<n ;i++){//只能交替染色,如果是s1[i]!=s2[i]三个字符串最多只有两个对应位字符相等
if(s1[i]!=s2[i]){
if(flag)s3[i]=s1[i];
else s3[i]=s2[i];
vis[i]=true;
flag=!flag;
if(flag)cnt++;//交替染完一次色
if(cnt==t)return ;
}
}
}
int main(){
// freopen("in.txt", "r", stdin);
// freopen("out.txt", "w", stdout);
scanf("%d %d",&n,&t);
scanf("%s",s1);
scanf("%s",s2);
t=n-t;
solve();
s3[n]='\0';
if(cnt<t){ puts("-1");return 0;}
for(int i=0 ; i<n ; i++){
if(!vis[i]){
for(char j='a' ; j<='z' ; j++){
if(s1[i]!=j&&s2[i]!=j){
s3[i]=j;vis[i]=true;
break;
}
}
}
}
printf("%s\n",s3);
return 0;
}
传送门: D. Dima and Lisa (数论,暴力)
题意:
给你一个奇数n
你可以见这个素数拆分成1,2或3个素数的和,将其输出,结果不唯一。
思路:
题源是
哥德巴赫猜想
任一大于2的偶数都可写成两个质数之和。
任一大于7的奇数都可写成三个素数之和。
任一大于7的奇数都可写成三个素数之和。
首先得知道一个数学规律,在小于10^9的素数中相邻两个素数之间的的距离不会超过300,。
知道上面的规律后解这个题暴力就行了。
通过分析我们可以知道:
1个:本身就是素数。
2个:因为给的是奇数,所以两个拆出来的数一定是一奇一偶,既是偶数又是素数的数只有2,所以我们只需判断n-2是否为素数即可。
3个:先找一个比n小的素数(尽量靠近n),根据上面的那个规律,所以我们就能很快的找到另一个素数。在做差以后得到x(x<=300),剩下的两个数就在x里面暴力寻找即可。
#include <bits/stdc++.h>
#define ll __int64
using namespace std;
const int inf=0x3f3f3f3f;
int n;
bool prime(int n){
for(int i=2 ; i*i<=n ; i++){
if(n%i==0)return false;
}
return true;
}
int main(){
// freopen("in.txt", "r", stdin);
// freopen("out.txt", "w", stdout);
while(~scanf("%d",&n)){
if(prime(n))printf("1\n%d",n);
else if(prime(n-2))printf("2\n2 %d",n-2);
else{
int m=n;
while(!prime(m))m--;
int t=n-m;
for(int i=2 ; i<=t ; i++){
if(prime(i)&&prime(t-i)){
printf("3\n%d %d %d",i,t-i,m);
break;
}
}
}
}
return 0;
}
总结:这场比赛主要涉及数学知识,并没有太多高深的算法,好像最后大家的解题量都很可观~