A:空间
B=Byte b=bit
1MB=1024KB
1KB=1024B
1B=8b
32b=4B
256MB=256*1024*1024B
so 256MB/32b=67108864个
B:卡片
#include <bits/stdc++.h>
using namespace std;
int s[10];
bool check(int x)
{
while (x)
{
int t = x % 10;
x /= 10;
if (--s[t] < 0)
return false;
}
return true;
}
int main()
{
for (int i = 0; i < 10; i++)
{
s[i] = 2021;
}
for (int i = 1;; i++)
{
if (!check(i))
{
cout << i - 1 << endl;
system("pause");
return 0;
}
}
system("pause");
return 0;
}
C:直线
解析:斜率和截距可唯一确定一条平面直线,注意斜率不存在的线,注意double特性
#include <bits/stdc++.h>
using namespace std;
const int N = 200000;
int n = 0;
struct Line
{
double k, b;
bool operator<(const Line &t) const
{
if (k != t.k)
return k < t.k;
return b < t.b;
}
} I[N];
int main()
{
for (int x1 = 0; x1 < 20; x1++)
{
for (int y1 = 0; y1 < 21; y1++)
{
for (int x2 = 0; x2 < 20; x2++)
{
for (int y2 = 0; y2 < 21; y2++)
{
if (x1 != x2)
{
double k = (double)(y2 - y1) / (x2 - x1);
double b = (double)(y1 - k * x1);
I[n++] = {k, b};
}
}
}
}
}
sort(I, I + n);
int res = 1;
for (int i = 1; i < n; i++)
if (fabs(I[i].k - I[i - 1].k) > 1e-8 || fabs(I[i].b - I[i - 1].b) > 1e-8)
res++;
cout << res + 20 << endl;
system("pause");
return 0;
}
D:货物摆放
约数求组合:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int main()
{
ll n;
cin >> n;
vector<ll> d;
for (ll i = 1; i * i <= n; i++)
{
if (n % i == 0)
{
d.push_back(i);
if (n / i != i)
d.push_back(n / i);
}
}
int res = 0;
for (auto a : d)
{
for (auto b : d)
{
for (auto c : d)
{
if (a * b * c == n)
{
res++;
}
}
}
}
cout << res << endl;
system("pause");
return 0;
}//2430
暴力模拟+剪枝:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int main()
{
ll n;
cin >> n;
int res = 0;
for (ll i = 1; i * i * i <= n; i++)
{
if (n % i == 0)
{
for (ll j = i; i * j * j <= n; j++)
{
if (n / i % j == 0)
{
ll k = n / i / j;
if (i == j && j == k)
res++;
else if (i != j && j != k)
{
res += 6;
}
else
{
res += 3;
}
}
}
}
}
cout << res << endl;
system("pause");
return 0;
}
E:路径
动态滚动:
#include <bits/stdc++.h>
using namespace std;
int dp[2021];//表示到1的距离
int lcm(int a, int b)
{
return a / __gcd(a, b) * b;
}
void init()//初始化
{
for (int i = 1; i <= 2021; i++)
{
dp[i] = 20212021;//INF
}
}
int main()
{
init();
dp[1] = 0;
for (int i = 2; i <= 22; i++)
{
dp[i] = i;
}
for (int i = 2; i <= 2021; i++)
{
for (int k = 1; k <= 21; k++)
{
if ((i - k) >= 1)
{
dp[i] = min(dp[i], dp[i - k] + lcm(i - k, i));
}
}
}
cout << dp[2021] << endl;
system("pause");
return 0;
}//10266837
F:时间显示
1秒==1000ms
不知道也没关系,样例给的好,可以试出来
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int main()
{
ll n;
cin >> n;
n /= 1000;
n %= 86400;
int h = n / 3600;
n %= 3600;
int m = n / 60;
int s = n % 60;
printf("%02d:%02d:%02d", h, m, s);
system("pause");
return 0;
}
G:砝码称重
本人超喜欢喜欢bitset
#include <bits/stdc++.h>
using namespace std;
bitset<200021> ans, tmp;
//0的位置
#define W 100010
//总长度
#define len 200021
int n;
int arr[105];
void moni()
{
for (int i = 0; i < W; i++)
{
if (ans[i])
{
ans[len - 1 - i] = 1;
ans[i] = 0;
}
}
}
int main()
{
cin >> n;
for (int i = 0; i < n; i++)
{
cin >> arr[i];
}
ans[W] = 1;
for (int i = 0; i < n; i++)
{
tmp.reset();
tmp[W] = 1;
tmp = tmp | (ans << arr[i]);
tmp = tmp | (ans >> arr[i]);
ans = ans | tmp;
moni();
}
cout << ans.count() - 1 << endl;
system("pause");
return 0;
}
H:杨辉三角形
偶数行的个数是奇数个,其中最中间的数是最大的,也是“跑”的最快的,如果一个目标值比增长最快的数还大的话,就往后所在的斜行找
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int n;
ll C(int a, int b)
{
ll res = 1;
for (int i = a, j = 1; j <= b; i--, j++)
{
res = res * i / j;
if (res > n)
return res;
}
return res;
}
bool check(int k)
{
ll l = 2 * k, r = n;
while (l < r)
{
ll mid = l + r >> 1;
if (C(mid, k) >= n)
r = mid;
else
l = mid + 1;
}
if (C(r, k) != n)
return false;
cout << r * (r + 1) / 2 + k + 1;
return true;
}
int main()
{
cin >> n;
for (int k = 16;; k--)
{
if (check(k))
break;
}
system("pause");
return 0;
}
I:双向排序
![在这里插入图片描述](https://img-blog.csdnimg.cn/2021050916031864.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L01vUmFuMF8w,size_16,color_FFFFFF,t_70
#include <iostream>
#define x first
#define y second
using namespace std;
typedef pair<int, int> PII;
const int N = 100010;
int n, m;
PII stk[N];//第一关键词存什么操作,第二关键词存操作下标
int ans[N];
int main()
{
cin >> n >> m;
int tt = 0;
while (m -- )
{
int p, q;
cin >> p >> q;
if (!p) //前缀操作
{
while (tt && stk[tt].x == 0) q = max(q, stk[tt -- ].y); //对于连续的前缀操作,保留最长的
while (tt >= 2 && stk[tt - 1].y <= q) tt -= 2; //直至遇到后缀操作,删除前面所有长度比当前小的前缀操作(以及与之配套的后缀操作)
stk[ ++ tt] = {0, q};
}
else if (tt)//后缀操作,第一个操作一定不是后缀操作
{
while (tt && stk[tt].x == 1) q = min(q, stk[tt -- ].y);
while (tt >= 2 && stk[tt - 1].y >= q) tt -= 2;
stk[ ++ tt] = {1, q};
}
}
//处理操作,每次都是缩小端点
int k = n, l = 1, r = n;
for (int i = 1; i <= tt; i ++ )
{
if (stk[i].x == 0) //前缀操作,前缀操作端点后面的已经确定(从n开始递减)
while (r > stk[i].y && l <= r) ans[r -- ] = k -- ;
else //后缀操作,后缀操作端点前面的已经确定(继续递减)
while (l < stk[i].y && l <= r) ans[l ++ ] = k -- ;
if (l > r) break;
}
//处理最后一次操作,这次操作是真操作,端点两边已经动完了
if (tt % 2) //最后一次操作是前缀操作
while (l <= r) ans[l ++ ] = k -- ;
else //最后一次操作是后缀操作
while (l <= r) ans[r -- ] = k -- ;
for (int i = 1; i <= n; i ++ )
cout << ans[i] << ' ';
cout << endl;
return 0;
}
J:扩号序列
#include <algorithm>
#include <cstring>
#include <iostream>
using namespace std;
typedef long long LL;
const int N = 5010, MOD = 1e9 + 7;
int n;
char str[N];
LL f[N][N];
LL work()
{
memset(f, 0, sizeof f);
f[0][0] = 1;
for (int i = 1; i <= n; i++)
if (str[i] == '(')
{
for (int j = 1; j <= n; j++)
f[i][j] = f[i - 1][j - 1];
}
else
{
f[i][0] = (f[i - 1][0] + f[i - 1][1]) % MOD;
for (int j = 1; j <= n; j++)
f[i][j] = (f[i - 1][j + 1] + f[i][j - 1]) % MOD;
}
for (int i = 0; i <= n; i++)
if (f[n][i])
return f[n][i];
return -1;
}
int main()
{
scanf("%s", str + 1);
n = strlen(str + 1);
LL l = work();
reverse(str + 1, str + n + 1);
for (int i = 1; i <= n; i++)
if (str[i] == '(')
str[i] = ')';
else
str[i] = '(';
LL r = work();
printf("%lld\n", l * r % MOD);
system("pausse");
return 0;
}