感觉最近做题太少,昨晚上一时兴起注册了晚上十二点半的CF,做到了两点半,没想到最后把C绝杀了,rating上升了一些,还不错。早上起来把D也过了,稍微总结一下。
题解:
让你输出一个能被t整除的n位数字,刚开始看样例吓到了,这么大怎么去存,没有思路,后来慢慢往t突破,t的范围2~10,想找能被这些数整除的数的性质,自己凑一个数。分情况讨论交了一遍后才发现自己傻逼了,干嘛不每一位都是t呐?只有10的时候另外讨论。。。马上改代码核心不到10行,又因为1,10这样的-1的情况没有讨论wa了一次,就这样A跌跌撞撞过了。
代码实现:
#include <bits/stdc++.h>
using namespace std;
const int MAX = 110;
int N,T;
int main()
{
scanf("%d%d",&N,&T);
if( N == 1 && T == 10 ){
printf("-1\n");
return 0;
}
if( T == 10 ){
for( int i = 0; i < N-1; i++ ){
printf("1");
}
printf("0\n");
}
else{
for( int i = 0; i < N; i++ ){
printf("%d",T);
}
printf("\n");
}
return 0;
}
Kolya loves putting gnomes at the circle table and giving them coins, and Tanya loves studying triplets of gnomes, sitting in the vertexes of an equilateral triangle.
More formally, there are 3n gnomes sitting in a circle. Each gnome can have from 1 to 3 coins. Let's number the places in the order they occur in the circle by numbers from 0 to 3n - 1, let the gnome sitting on the i-th place have ai coins. If there is an integer i (0 ≤ i < n) such that ai + ai + n + ai + 2n ≠ 6, then Tanya is satisfied.
Count the number of ways to choose ai so that Tanya is satisfied. As there can be many ways of distributing coins, print the remainder of this number modulo 109 + 7. Two ways, a and b, are considered distinct if there is index i (0 ≤ i < 3n), such thatai ≠ bi (that is, some gnome got different number of coins in these two ways).
A single line contains number n (1 ≤ n ≤ 105) — the number of the gnomes divided by three.
Print a single number — the remainder of the number of variants of distributing coins that satisfy Tanya modulo 109 + 7.
1
20
2
680
20 ways for n = 1 (gnome with index 0 sits on the top of the triangle, gnome 1 on the right vertex, gnome 2 on the left vertex):
题解:
这道题还是比较裸的,就是一个简单的动态规划,找到递推式就很好做了,一遍过。
代码实现:
#include <bits/stdc++.h>
#define LL long long
using namespace std;
const int MAX = 100010;
const int mod = 1000000000+7;
int N;
LL dp[MAX];
LL Time[MAX];
int main()
{
scanf("%d",&N);
memset(dp,0,sizeof(dp));
memset(Time,0,sizeof(Time));
dp[1] = 20;
Time[0] = 1;
Time[1] = 7;
for( int i = 2; i <= N; i++ ){
dp[i] = (27*dp[i-1]%mod+20*Time[i-1]%mod)%mod;
Time[i] = Time[i-1]*7%mod;
}
printf("%I64d\n",dp[N]);
return 0;
}
题解:
自已眼看这道题感觉在那里做过。。。有两个字符串,求第三个字符串使其与前两个串的差异度都是t。那关键点肯定是串1和串2的相似度啊。分情况讨论把,看看目标差异度t和str1,str2固有差异度x之间的相对关系。
第一种:t<=len && t>=x;
这时候首先保证str1,str2不同时str3也和他们都不同,剩下配上几个他们两个相同的情况。
第二种:t >= x/2;
为什么是len/2?因为这个时候他们要重叠一部分,也就是说在str1和str2不相同的那一段上,str3要分别有x-t的长度和str1,str2一样。另外t = x/2 的时候要另外讨论,毕竟x的奇偶性不太清楚,多一个都不行。
剩下的就是不符合的情况;
最后5分钟绝杀,好险好险。。。
代码实现:
#include <bits/stdc++.h>
using namespace std;
const int MAX = 100010;
int N,T;
int cnt;
int len;
bool flag;
int tag[MAX];
char str1[MAX];
char str2[MAX];
char str3[MAX];
char get(char a,char b);
int main()
{
scanf("%d%d",&N,&T);
scanf("%s",str1);
scanf("%s",str2);
flag = true;
cnt = 0;
len = strlen(str1);
memset(tag,0,sizeof(tag));
for( int i = 0; i < len; i++ ){
if( str1[i] != str2[i] ){
cnt++;
tag[i] = 1;
}
}
if( T>=cnt && T<=len ){
for( int i = 0; i < len; i++ ){
if( tag[i] == 1 ){
str3[i] = get(str1[i],str2[i]);
T--;
}
else{
str3[i] = str1[i];
}
}
for( int i = 0; i < len; i++ ){
if( T == 0 ){
break;
}
if( tag[i] == 0 ){
str3[i] = get(str1[i],str2[i]);
T--;
}
}
}
else if( T>=cnt/2 ){
if( T == cnt/2 ){
if( cnt%2 == 0 ){
int tmp = cnt/2;
int pos = 0;
while( tmp ){
str3[pos] = str1[pos];
if( tag[pos] == 1 ){
tmp--;
}
pos++;
}
tmp = cnt/2;
while( tmp ){
str3[pos] = str2[pos];
if( tag[pos] == 1 ){
tmp--;
}
pos++;
}
while( pos < len ){
str3[pos] = str1[pos];
pos++;
}
}
else{
flag = false;
}
}
else{
int tmp = cnt-T;
int pos = 0;
while( tmp ){
str3[pos] = str1[pos];
if( tag[pos] == 1 ){
tmp--;
}
pos++;
}
tmp = cnt-T;
while( tmp ){
str3[pos] = str2[pos];
if( tag[pos] == 1 ){
tmp--;
}
pos++;
}
while( pos < len ){
str3[pos] = str1[pos];
if( tag[pos] == 1 ){
str3[pos] = get(str1[pos],str2[pos]);
}
pos++;
}
}
}
else{
flag = false;
}
if( flag == false ){
printf("-1\n");
}
else{
printf("%s\n",str3);
}
return 0;
}
char get(char a,char b){
int na = (int)a;
int nb = (int)b;
if( na == nb ){
if( a != 'a' ){
return char(na-1);
}
else{
return char(na+1);
}
}
else{
if( na < nb ){
swap(na,nb);
}
if( na-nb > 1 ){
return char(na-1);
}
else{
if( a!='a' && b!='a' ){
return char(nb-1);
}
else{
return char(na+1);
}
}
}
}
题解:
把一个大奇数分成最多三个质数的和,我靠,像不像哥德巴赫猜想??然并不会啊,毕竟不是数学专业,竟是硬伤,暴力筛素数然后深搜试了一下,内存和时间各爆了一回。后来看了一下数据,如果是暴力搜的话前一个或两个素数应该不会太大的,超时和爆内存都是在筛法上,改成了10^3。吓,竟然过了。但是后来看了看别人的代码,果然是得先推一下再去解的。。。。先冷静一下吧。
代码实现:
#include <bits/stdc++.h>
using namespace std;
const int MAX = 1010;
int N;
int sum;
int len;
bool flag;
int save[3];
int prime[MAX];
bool if_prime[MAX];
int pre(int num);
bool ifp(int n);
void dfs(int num,int pos,int tag);
int main()
{
sum = pre(1000);
while( scanf("%d",&N) != EOF ){
len = 0;
flag = false;
dfs(N,0,0);
printf("%d\n",len);
for( int i = 0; i < len; i++ ){
printf("%d",save[i]);
if( i != len-1 ){
printf(" ");
}
else{
printf("\n");
}
}
}
return 0;
}
int pre(int num){
int pos = 0;
for( int i = 1; i <= num; i++ ){
if_prime[i] = true;
}
memset(prime,0,sizeof(prime));
for( int i = 2; i <= num; i++ ){
if( if_prime[i] == false ){
continue;
}
prime[pos++] = i;
for( int j=2*i; j <= num; j+=i ){
if_prime[j] = false;
}
}
return pos;
}
void dfs(int num,int pos,int tag){
if( pos >= 3 ){
return ;
}
if( ifp(num) ){
save[pos] = num;
pos++;
len = pos;
flag = true;
return ;
}
for( int i = tag; tag < sum; i++ ){
if( prime[i] > num ){
break;
}
save[pos] = prime[i];
dfs(num-prime[i],pos+1,i);
if( flag == true ){
break;
}
}
return ;
}
bool ifp(int n){
for( int i = 0; i < sum; i++ ){
if( n%prime[i] == 0 ){
return false;
}
if( prime[i]*prime[i] > n ){
break;
}
}
return true;
}
再贴一个牛逼点的代码。。。T T
#include<bits/stdc++.h>
#define f(i,a,b) for(i=a;i<b;i++)
using namespace std;
int prime(int n)
{
for(int i=2;i*i<=n;i++)if(n%i==0)return 0;
return 1;
}
int main()
{
int n,i;
cin>>n;
if(prime(n)){printf("1\n%d",n);return 0;}
printf("3\n3 ");
n-=3;
for(i=3;;i+=2)if(prime(i)&&prime(n-i)){printf("%d %d",i,n-i);return 0;}
}