A. Olesya and Rodion
题意:
给你N位数,然后给一个数字t,问你是否能不能找到这样的一个N位数,使得能被t整除。
思路:
因为数据量在2到10之间,所以分等于10,和不等于10来看。当t=10时,这时候只需要最后一位是0那么就能整除10,不过这要N>1,因为等于1是不可能的。当t<10时,只需要这个N位数每一个位置上的数都与t相等就行了。
code:
#include<iostream>
#include<fstream>
using namespace std;
int main()
{
int n, t;
cin >> n >> t;
if (t == 10)
{
if (n == 1)
cout << -1 << endl;
else
{
for (int i = 1; i < n; i++)
cout << 1;
cout << 0 << endl;
}
}
else
{
for (int i = 0; i < n; i++)
cout << t;
cout << endl;
}
}
题意:
这道题给给你3N个数字,每个数字的数据范围都在1到3,问你每ai + ai + n + ai + 2n ≠ 6能得到的方法有多少个。仔细观察一下,一定就知道这道题 其实是让你来找规律。我们想象怎么才能这些.其实首先判断一下除开特殊情况,有多少种排法,3的3N次方,换言之就是27的N次方,然后这时候计算一下等于6的情况有哪些,3*2*1+1,最后的那个1是代表着所有的数字都是值为2.
所以最后的通项公式为 27^n-7^n
#include<iostream>
#include<string>
using namespace std;
const long long mod = 1e9 + 7;
int main()
{
int n;
cin >> n;
long long n27=1, n7=1;
while (n--)
{
n27 = (n27*27) % mod;
n7 = (n7*7) % mod;
}
int ans = (n27 - n7 + mod) % mod;
cout << ans << endl;
}
C. Marina and Vasya
题意:
给你相等长度的两个字符串,现在要求你要找一个字符串,使这个字符串与这两个字符串对应的位置有t个不相等。
思路:
题目说首先给你字符串的长度N,然后给你这个字符串有多少个不相等的字符,所以换个角度来看,那么N-t就代表着有多少个相等的字符串,我们把这个定义为K,那么因为下面两个字符串有些位置可能相等,那么我们把这些相等的位置的数量定义为Q,如果K>Q,那么说明了这些Q个完全可以属于新的字符串(位置与其余两个字符串位置相同),那么剩下的K-Q个字符,有些属于字符串1,有些属于字符串2,现在还剩下N-K个字符串与其余两个字符串对应位置的字符完全不一样,这个现在只需要随机一下就可以出结果了。
对于K<Q的情况更简单,只需要在这Q个任意选取K个就行,剩下的就随机成既不等于字符串1又不等于字符串2
#include<iostream>
#include<string>
#include<random>
using namespace std;
int len[111111];
int main()
{
int n, t;
cin >> n >> t;
string a, b;
char c[111111]="";
cin >> a >> b;
int sum = 0;
random_device rd;
for (int i = 0; i < n; i++)
{
if (a[i] == b[i])
sum++, len[i] = 1;
}
if (n - t <= sum)
{
int k = n - t;
for (int i = 0; i < n; i++)
{
if (len[i]&&k)
{
c[i] = a[i];
k--;
}
else
{
int ra;
char ca;
do
{
ra = rd() % 26;
ca = 'a' + ra;
} while (ca == a[i] || ca == b[i]);
c[i] = ca;
}
}
c[n] = (char)0;
cout << c << endl;
}
else
{
if (2 * (n - t - sum) > (n - sum))
cout << -1 << endl;
else
{
int k = 2*(n - t - sum);
int eq = sum;
bool flag = true;
for (int i = 0; i < n; i++)
{
if (len[i] && eq)
{
c[i] = a[i];
eq--;
}
else
{
if (k)
{
if (flag)
{
c[i] = a[i];
flag = false;
}
else
{
c[i] = b[i];
flag = true;
}
k--;
}
else
{
int ra;
char ca;
do
{
ra = rd() % 26;
ca = 'a' + ra;
} while (ca == a[i] || ca == b[i]);
c[i] = ca;
}
}
}
c[n] = '\0';
cout << c << endl;
}
}
return 0;
}
D. Dima and Lisa
题意:
给你一个数字,现在需要你来找到任意1到3个素数,使他们加起来的和为这个数。
思路:
这道题的数字最大能达到10的9次方,所以先素数打表是然后来找是不好找到的,或者说这么大的素数范围空间不够,所以需要用上一些数论知识,在10^9里面两个素数的距离最大只达到281,。所以只需要先暴力出一个离数字N的最近的一个素数D,然后N-D的最大也就300。。。。,暴力就对了(然而不知道素数最大的距离是300的也没法想到这个方法)。最后还是看官方题解才解决的,数论真心不会=-=。
#include<iostream>
#include<string>
#include<cmath>
using namespace std;
const int maxn = 100;
bool isPrime(int N)
{
//int n = static_cast<int>(sqrt((float)N));
for (int i = 2; i*i <= N; i++)
{
if (N%i==0)
return true;
}
return false;
}
int main()
{
int N;
cin >> N;
if (N <= 7)
cout << 1 << "\n" << N;
else
{
cout << 3 << endl;
for (int i = N-1; i; i--)
{
if (!isPrime(i))
{
int d = N - i;
for (int j = 2; j < d; j++)
{
if (!isPrime(j) &&!isPrime(d-j))
{
cout << i << " " << j << " " << d-j << endl;
return 0;
}
}
}
}
}
return 0;
}