1.RAS
思路:
先判断a和b是否相等,如果相等直接输出no credit,求出a和b的所有因子,并记录下所有因子的出现次数,如果有一个因子出现了两次以上,或者已经有一个因子是某个数的平方数时,输出no credit,如果这两个数没有除了1和自身以外的数,就输出full credit,剩余情况输出partial credit
#define _CRT_SECURE_NO_WARNINGS
#include<bits/stdc++.h>
#include <unordered_map>
#define int long long
using namespace std;
map<int, int>yinzi;
bool zhi(int a) {
int panduan = 1;
for (int e = 2; e <= sqrt(a); e++) {
if (a % e == 0) {
panduan = 0;
break;
}
}
return panduan;
}
void yin(int a) {
for (int e = 2; e <= a/e; e++) {
if (a % e == 0) {
yinzi[e]++;
yinzi[a / e]++;
}
//printf("%lld\n", e);
}
//cout << "HH" << endl;
}
signed main() {
int a, b;
cin >> a >> b;
if (a == b) {
cout << "no credit";
return 0;
}
if (a != b && zhi(a) && zhi(b)) {
cout << "full credit";
return 0;
}
yin(a);
yin(b);
map<int, int>::iterator it;
for (it = yinzi.begin(); it != yinzi.end(); it++) {
int zan = sqrt(it->first);
if (zan * zan == it->first || it->second > 1) {
cout<< "no credit";
return 0;
}
}
cout << "partial credit";
}
2.数组操作
思路:
题目看起来很复杂,实际意思就是把整个数组变成最后一个数,怎么变呢,从后开始找,直到第一个和最后一个数不相等的数,然后把这个数后的区间覆盖到这个数前,比如本来是01234777,变成01777777,然后接着从后开始找,每覆盖一次ans++,最后输出ans即可
#define _CRT_SECURE_NO_WARNINGS
#include<bits/stdc++.h>
using namespace std;
vector<int>shuzu;
int main() {
int asdf;
cin >> asdf;
while (asdf--) {
int a;
cin >> a;
shuzu.clear();
while (a--) {
int b;
cin >> b;
shuzu.push_back(b);
}
int ans = 0;
int daxiao = 1;
int jiluzh = shuzu.size() - 1;
while (jiluzh>0) {
for (int e = jiluzh-1; e >= 0; e--) {
if (shuzu[e] != shuzu[shuzu.size() - 1]) {
jiluzh = e + 1;
break;
}
if (e == 0) {
jiluzh = 0;
break;
}
daxiao++;
}
if (jiluzh <= 0) {
break;
}
ans++;
jiluzh -= daxiao;
daxiao *= 2;
//cout << daxiao << endl;
//cout << jiluzh << endl;
system("pause");
}
cout << ans << endl;
}
}
三.A-B数对
思路:
建立一个数组统计每个数出现的次数,另一个动态数组统计有多少种数,之后遍历动态数组,如果有和当前位匹配的数,和+=当前位数的数量*匹配的数的数量,最后输出和
#define _CRT_SECURE_NO_WARNINGS
#include<bits/stdc++.h>
using namespace std;
#define int long long
int shu[10000000];
vector<int>shu2;
signed main() {
int a, b;
cin >> a >> b;
while (a--) {
int c;
cin >> c;
shu[c]++;
if (shu[c] == 1) {
shu2.push_back(c);
}
}
int he = 0;
for (int e = shu2.size()-1; e >= 0; e--) {
if (shu2[e]-b>=0&&shu[shu2[e] - b] >= 1) {
he = he+shu[shu2[e]] * shu[shu2[e] - b];
}
}
cout << he;
}
四.数位计算
思路:
分段求解,用等差数列公式算出每个区间的和然后加起来
#define _CRT_SECURE_NO_WARNINGS
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int mod = 998244353;
signed main() {
string a;
cin >> a;
reverse(a.begin(), a.end());
unsigned long long he = 0;
int shu = 0;
for (int e = a.size() - 1; e >= 0; e--) {
shu *= 10;
shu += a[e] - '0';
}
for (int e = 0; e < a.size(); e++) {
if (e != a.size() - 1) {
if (e == 0) {
he += 45;
he %= mod;
}
else {
int a3 = pow(10, e + 1);
int a4 = pow(10, e);
unsigned long long a1 = ((a3 - 1 - a4 + 1) + 1);
a1 %= mod;
unsigned long long a2 = (a3 - 1 - a4 + 1);
a2 %= mod;
he +=(a1* a2/2)%mod;
}
}
else {
int aaa = pow(10, e);
unsigned long long linshi = shu - aaa + 1;
linshi %= mod;
unsigned long long linshi2 = shu - aaa + 2;
linshi2 %= mod;
unsigned long long l2 = linshi2 * linshi / 2;
l2 %= mod;
he += l2;
}
}
cout << he%mod;
}
五.新国王游戏
思路:
自定义排序,当两个人谁在前总收益大时,谁在前就是最优排序,抽象放大到整个队列,之后计算结果;
#define _CRT_SECURE_NO_WARNINGS
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int mod = 1000000007;
bool cmp(pair<int ,int>a,pair<int,int>b) {
return b.second + a.second * b.first < a.second + b.second * a.first;
}
vector<pair<int, int>>ren;
signed main() {
int n;
cin >> n;
while (n--) {
int a, b;
cin >> a >> b;
ren.push_back(make_pair(a,b));
}
sort(ren.begin(), ren.end(), cmp);
int res =ren[0].second;
int sum = 1;
for (int e =0; e<ren.size(); e++) {
if (e > 0)res = (res + (sum * ren[e].second) % mod) % mod;
sum = (sum * ren[e].first) % mod;
}
cout << res;
}
六.完美数
思路:
就是说给你m个位置,你可以在每个位置放a或者b,如果所有位置的和加起来之后的数的每个位置还是a或者b,那它就是完美数,我们可以用排列组合来解决这个问题,从0个a,m个b一直到m个a,0个b,如果符合,就加上排列组合数,取模的话遇到一些小问题,可以在计算排列组合时利用逆元和快速幂来解决这个问题
#define _CRT_SECURE_NO_WARNINGS
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int mod = 1e9 + 7;
const int N = 1e6;
int biao[N+5];
int a, b, m;
int panduan(int c) {
while (c) {
if (c % 10 != a && c % 10 != b) {
return 0;
}
c /= 10;
}
return 1;
}
inline int ksm(int a, int b, int p) {
int ans = 1;
while (b) {
if (b & 1) { ans= ans* a % p; }
a = a * a % p;
b >>=1;
}
return ans;
}
int jieguo(int c) {
return biao[m] % mod * ksm(biao[m - c], mod - 2, mod) % mod * ksm(biao[c], mod - 2, mod) % mod;
}
signed main() {
cin >> a >> b >> m;
biao[0] = 1;
for (int e = 1; e <=N; e++) {
biao[e] = (biao[e - 1] * e )% mod;
}
int he = 0;
for (int e = 0; e <=m; e++) {
int xy = a * e + b * (m - e);
if (panduan(xy)) {
he += jieguo(e)%mod;
he %= mod;
// cout << he << endl;
}
}
cout << he%mod;
}
七.Lusir的游戏
思路:
数据不大,直接二分过了
#define _CRT_SECURE_NO_WARNINGS
#include<bits/stdc++.h>
using namespace std;
#define int long long
vector<int>tu;
signed main() {
int n;
cin >> n;
int maxx= 0;
while (n--) {
int b;
cin >> b;
tu.push_back(b);
if (b > maxx) {
maxx = b;
}
}
int l = 0, r = maxx;
while (l+1< r) {
double mid = (l + r) / 2;
double nl = mid;
int panduan = 1;
//cout << "nl" << nl << endl;
for (int e = 0; e <tu.size(); e++) {
nl = nl+(nl - tu[e]);
if (nl < 0) {
panduan = 0;
break;
}
}
//cout << "panduan" << panduan << endl;
if (panduan) {
r = mid;
}
else {
l = mid;
}
//cout << l << " " << r<<endl;
}
int panduan = 1;
int nl = l;
for (int e = 0; e < tu.size(); e++) {
nl = nl + (nl - tu[e]);
if (nl < 0) {
panduan = 0;
break;
}
}
if (panduan) {
cout << l;
}
else {
cout << r;
}
}
八.BFS练习1
思路:
bfs跑一遍
#include<bits/stdc++.h>
using namespace std;
const int N = 300050;
int a[N], f[N];
int main()
{
ios_base::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
int n, num;
cin >> num >> n;
vector<int>v(n);
for (int i = 0; i < n; i++)
{
cin >> v[i];
a[v[i]] = -1;
}
queue<int>que;
que.push(num);
int res = 0;
while (!que.empty() && n)
{
int len = que.size();
for (int i = 0; i < len; i++)
{
int ans = que.front();
que.pop();
if (a[ans] == -1)
{
a[ans] = res;
n--;
}
if (ans * 3 < 100050 && f[ans * 3] == 0)
{
que.push(ans * 3);
f[ans * 3] = 1;
}
if (ans * 2 < 100050 && f[ans * 2] == 0)
{
que.push(ans * 2);
f[ans * 2] = 1;
}
if (ans - 1 > 0 && f[ans - 1] == 0)
{
que.push(ans - 1);
f[ans - 1] = 1;
}
if (ans + 1 < 100050 && f[ans + 1] == 0)
{
que.push(ans + 1);
f[ans + 1] = 1;
}
}
res++;
}
for (auto i : v)
{
cout << a[i]<<" ";
}
return 0;
}
九.01序列2
思路:
我们只要保证两个1之间有k个0就行,剩下的位置可以随便排列
#define _CRT_SECURE_NO_WARNINGS
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<ll, ll>PII;
const int N = 1000050, MOD = 1e9 + 7;
ll fact[N], infact[N];
ll qmi(int a, int b)
{
ll res = 1;
while (b)
{
if (b & 1) res = res * a % MOD;
a = a * (ll)a % MOD;
b >>= 1;
}
return res;
}
void init()
{
fact[0] = infact[0] = 1;
for (int i = 1; i < N; i++)
fact[i] = fact[i - 1] * i % MOD;
infact[N - 1] = qmi(fact[N - 1], MOD - 2);
for (int i = N - 2; i; i--)
infact[i] = infact[i + 1] * (i + 1) % MOD;
}
int C(int a, int b)
{
return (fact[a] * infact[b] % MOD * infact[a - b] % MOD) % MOD;
}
int main()
{
ios_base::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
int n, k;
init();
cin >> n >> k;
int i = 1;
ll res = 1;
while (i <= n - (i - 1) * k)
{
res = (res + C(n - (i - 1) * k, i) % MOD) % MOD;
i++;
}
cout << res << endl;
return 0;
}
十.整除光棍
思路:
我们就直接枚举所有光棍数就可以了,看那个光棍数能被x整除,最后输出枚举的光棍数长度和商即可。同时因为数据大所以我们需要用到高精度.
#define _CRT_SECURE_NO_WARNINGS
#include<bits/stdc++.h>
using namespace std;
const int N = 1000050, MOD = 1e9 + 7;
typedef long long ll;
int n;
void write(int x) {
if (x > 9) write(x / 10);
putchar(x % 10 | '0');
}
int main()
{
ios_base::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
cin >> n;
int r = 1, ans = 1;
while (r < n)
{
r *= 10;
r += 1;
ans++;
}
while (1)
{
write(r / n);
r %= n;
if (r == 0)break;
ans++;
r *= 10;
r += 1;
}
putchar(' ');
write(ans);
return 0;
}