#include
#define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define _for(n,m,i) for (register int i = (n); i < (m); ++i)
#define _rep(n,m,i) for (register int i = (n); i <= (m); ++i)
#define lson rt<<1, l, mid
#define rson rt<<1|1, mid+1, r
#define PI acos(-1)
#define eps 1e-8
#define rint register int
using namespace std;
typedef long long LL;
typedef pair<LL, int> pli;
typedef pair<int, int> pii;
typedef pair<double, int> pdi;
typedef pair<LL, LL> pll;
typedef pair<double, double> pdd;
typedef map<int, int> mii;
typedef map<char, int> mci;
typedef map<string, int> msi;
template<class T>
void read(T &res) {
int f = 1; res = 0;
char c = getchar();
while(c < '0' || c > '9') {
if(c == '-') f = -1; c = getchar(); }
while(c >= '0' && c <= '9') {
res = res * 10 + c - '0'; c = getchar(); }
res *= f;
}
const int ne[8][2] = {
1, 0, -1, 0, 0, 1, 0, -1, -1, -1, -1, 1, 1, -1, 1, 1};
const int INF = 0x3f3f3f3f;
const int N = 210;
const LL Mod = 1e9+7;
const int M = 1e6+10;
int solve() {
int x = 10000, res = 0;
while(1) {
_for(0, 60, i) {
x -= 10; ++res;
if(x <= 0) return res;
}
x += 300; res += 60;
}
}
int main() {
cout << solve();
return 0;
}
答案: 3880(注意答案是以秒为单位输出!)
答案:52038720(36138 * 24 * 60)
题意:
做法:概率杀我 ,设A国共有100人,那么合并检测需要用的试剂为 100 k \frac{100}{k} k100个,均匀分布可以认为100个人里面就有一个人感染,所以,对于这一个人还需要个试剂,结果就是 100 k + k \frac{100}{k}+k k100+k,根据基本不等式,当 100 k = k \frac{100}{k}=k k100=k时,等式取到最小值,这时k=10。
答案:10
#include
#define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define _for(n,m,i) for (register int i = (n); i < (m); ++i)
#define _rep(n,m,i) for (register int i = (n); i <= (m); ++i)
#define lson rt<<1, l, mid
#define rson rt<<1|1, mid+1, r
#define PI acos(-1)
#define eps 1e-8
#define rint register int
using namespace std;
typedef long long LL;
typedef pair<LL, int> pli;
typedef pair<int, int> pii;
typedef pair<double, int> pdi;
typedef pair<LL, LL> pll;
typedef pair<double, double> pdd;
typedef map<int, int> mii;
typedef map<char, int> mci;
typedef map<string, int> msi;
template<class T>
void read(T &res) {
int f = 1; res = 0;
char c = getchar();
while(c < '0' || c > '9') {
if(c == '-') f = -1; c = getchar(); }
while(c >= '0' && c <= '9') {
res = res * 10 + c - '0'; c = getchar(); }
res *= f;
}
const int ne[8][2] = {
1, 0, -1, 0, 0, 1, 0, -1, -1, -1, -1, 1, 1, -1, 1, 1};
const int INF = 0x3f3f3f3f;
const int N = 210;
const LL Mod = 1e9+7;
const int M = 1e6+10;
string s;
stack<int> sk;
int main() {
freopen("prog.txt", "r", stdin);
int ci = 1;
LL res = 0;
while(getline(cin, s)) {
int pos = 0, len = s.size(), sj, mid;
while(pos < len && s[pos] == ' ') ++pos;
sj = pos / 4;
while(sk.size() > sj) {
ci /= sk.top();
sk.pop();
}
if(s[pos] == 'R') {
pos += 7;
for(mid = 0; pos < len-1; ++pos) mid = mid * 10 + s[pos]-'0';
sk.push(mid); ci *= mid;
} else {
pos += 8;
for(mid = 0; pos < len; ++pos) mid = mid * 10 + s[pos]-'0';
res += mid * ci;
}
//cout << mid << endl;
}
cout << res;
return 0;
}
答案:241830
题意:
做法:一看这题像dp,但是想不出转移方程 。f[i][j]表示第一行选i个数,第二行选j个数的总方案数,第二行能选的前提是第一行第j列有数。每个状态由上一个行和上一列转化而来,可以选择放在第一行或者第二行。这篇题解简单易懂。
代码:
#include
#define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define _for(n,m,i) for (register int i = (n); i < (m); ++i)
#define _rep(n,m,i) for (register int i = (n); i <= (m); ++i)
#define lson rt<<1, l, mid
#define rson rt<<1|1, mid+1, r
#define PI acos(-1)
#define eps 1e-8
#define rint register int
using namespace std;
typedef long long LL;
typedef pair<LL, int> pli;
typedef pair<int, int> pii;
typedef pair<double, int> pdi;
typedef pair<LL, LL> pll;
typedef pair<double, double> pdd;
typedef map<int, int> mii;
typedef map<char, int> mci;
typedef map<string, int> msi;
template<class T>
void read(T &res) {
int f = 1; res = 0;
char c = getchar();
while(c < '0' || c > '9') {
if(c == '-') f = -1; c = getchar(); }
while(c >= '0' && c <= '9') {
res = res * 10 + c - '0'; c = getchar(); }
res *= f;
}
const int ne[8][2] = {
1, 0, -1, 0, 0, 1, 0, -1, -1, -1, -1, 1, 1, -1, 1, 1};
const int INF = 0x3f3f3f3f;
const int N = 1020;
const int Mod = 2020;
const int M = 2020;
int f[N][N];
int main() {
f[0][0] = 1;
_for(0, N, i) _for(0, N, j) {
if(i > j) f[i][j] = (f[i][j] + f[i-1][j]) % Mod; //放在第二行
if(j) f[i][j] = (f[i][j] + f[i][j-1]) % Mod; //放在第一行
}
cout << f[1010][1010];
return 0;
}
答案:1340
——以下题目通过了 AcWing 的数据测试——
做法:记得开long long!!
代码:
#include
#define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define _for(n,m,i) for (register int i = (n); i < (m); ++i)
#define _rep(n,m,i) for (register int i = (n); i <= (m); ++i)
#define lson rt<<1, l, mid
#define rson rt<<1|1, mid+1, r
#define PI acos(-1)
#define eps 1e-8
#define rint register int
using namespace std;
typedef long long LL;
typedef pair<LL, int> pli;
typedef pair<int, int> pii;
typedef pair<double, int> pdi;
typedef pair<LL, LL> pll;
typedef pair<double, double> pdd;
typedef map<int, int> mii;
typedef map<char, int> mci;
typedef map<string, int> msi;
template<class T>
void read(T &res) {
int f = 1; res = 0;
char c = getchar();
while(c < '0' || c > '9') {
if(c == '-') f = -1; c = getchar(); }
while(c >= '0' && c <= '9') {
res = res * 10 + c - '0'; c = getchar(); }
res *= f;
}
const int ne[8][2] = {
1, 0, -1, 0, 0, 1, 0, -1, -1, -1, -1, 1, 1, -1, 1, 1};
const int INF = 0x3f3f3f3f;
const int N = 1020;
const int Mod = 2020;
const int M = 2020;
int main() {
LL n; scanf("%lld", &n);
printf("%lld", n);
n >>= 1;
while(n) {
printf(" %lld", n);
n >>= 1;
}
return 0;
}
做法:内部可能有数字有两位以上的情况,坑还是挺多的。
代码:
#include
#define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define _for(n,m,i) for (register int i = (n); i < (m); ++i)
#define _rep(n,m,i) for (register int i = (n); i <= (m); ++i)
#define lson rt<<1, l, mid
#define rson rt<<1|1, mid+1, r
#define PI acos(-1)
#define eps 1e-8
#define rint register int
using namespace std;
typedef long long LL;
typedef pair<LL, int> pli;
typedef pair<int, int> pii;
typedef pair<double, int> pdi;
typedef pair<LL, LL> pll;
typedef pair<double, double> pdd;
typedef map<int, int> mii;
typedef map<char, int> mci;
typedef map<string, int> msi;
template<class T>
void read(T &res) {
int f = 1; res = 0;
char c = getchar();
while(c < '0' || c > '9') {
if(c == '-') f = -1; c = getchar(); }
while(c >= '0' && c <= '9') {
res = res * 10 + c - '0'; c = getchar(); }
res *= f;
}
const int ne[8][2] = {
1, 0, -1, 0, 0, 1, 0, -1, -1, -1, -1, 1, 1, -1, 1, 1};
const int INF = 0x3f3f3f3f;
const int N = 1020;
const int Mod = 2020;
const int M = 2020;
string s;
int main() {
cin >> s;
int len = s.size(), pos = 0, mid;
char lst;
while(pos < len) {
if(isdigit(s[pos])) {
mid = 0;
while(pos < len && isdigit(s[pos])) mid = mid * 10 + s[pos] - '0', ++pos;
--mid;
_for(0, mid, i) printf("%c", lst);
} else printf("%c", s[pos]), lst = s[pos++];
}
puts("");
return 0;
}
题意:
做法:类似一个经典的dp,方格取数,只要行数和列数都为偶数时不更新dp[i][j]就能做到。
代码:
#include
#define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define _for(n,m,i) for (register int i = (n); i < (m); ++i)
#define _rep(n,m,i) for (register int i = (n); i <= (m); ++i)
#define lson rt<<1, l, mid
#define rson rt<<1|1, mid+1, r
#define PI acos(-1)
#define eps 1e-8
#define rint register int
using namespace std;
typedef long long LL;
typedef pair<LL, int> pli;
typedef pair<int, int> pii;
typedef pair<double, int> pdi;
typedef pair<LL, LL> pll;
typedef pair<double, double> pdd;
typedef map<int, int> mii;
typedef map<char, int> mci;
typedef map<string, int> msi;
template<class T>
void read(T &res) {
int f = 1; res = 0;
char c = getchar();
while(c < '0' || c > '9') {
if(c == '-') f = -1; c = getchar(); }
while(c >= '0' && c <= '9') {
res = res * 10 + c - '0'; c = getchar(); }
res *= f;
}
const int ne[8][2] = {
1, 0, -1, 0, 0, 1, 0, -1, -1, -1, -1, 1, 1, -1, 1, 1};
const int INF = 0x3f3f3f3f;
const int N = 40;
const int Mod = 2020;
const int M = 2020;
LL dp[N][N];
int main() {
int n, m;
scanf("%d%d", &n, &m);
dp[1][1] = 1;
_rep(1, n, i) _rep(1, m, j) {
if(i==1 && j==1) continue;
if((i&1) || (j&1)) dp[i][j] = dp[i-1][j] + dp[i][j-1];
}
printf("%lld\n", dp[n][m]);
return 0;
}
做法:正解就是把所有数扩大几倍后存起来,再用map找,要理解到,对于这些存起来的数字取膜k以后,只有两个数字加起来%k等于0才算一对,后面就能暴力了。用数组存每个数扩大10倍、100倍…十的十次方倍,存入a数组,再用一个vis充当map的作用,顺势记录这个数有多少位。
代码:
#include
using namespace std;
typedef long long LL;
const int N = 1e5 + 10;
LL a[N][11], x, mid;
int vis[N][11], n, k;
int cw(LL x) {
int res = 0;
while(x) {
++res; x /= 10;
}
return res;
}
int main() {
scanf("%d%d", &n, &k);
for(int i = 0; i < n; ++i) {
scanf("%lld", &x);
++vis[x%k][cw(x)]; a[i][0] = x;
for(int j = 1; j <= 10; ++j) a[i][j] = a[i][j-1] * 10 % k;
}
LL res = 0;
for(int i = 0; i < n; ++i) {
for(int j = 1; j <= 10; ++j) {
mid = k - a[i][j]; mid %= k;
if(vis[mid][j]) {
res += vis[mid][j];
if(a[i][0]%k == mid && cw(a[i][0]) == j) --res;
}
}
}
printf("%lld\n", res);
return 0;
}
题意:
做法:用w数组记录该点所有子孙都需要+的权值,每次合并都下传标记,复杂度n^2,极限卡常
代码:
#include
using namespace std;
const int N = 1e4+10;
int w[N], fa[N], res[N];
int Find(int x) {
return fa[x] == x ? x : fa[x] = Find(fa[x]);
}
int n, m;
void Merg(int x, int y) {
int fx = Find(x), fy = Find(y);
if(fx != fy) {
for(register int i = 1; i <= n; ++i) res[i] += w[Find(i)];
memset(w, 0, sizeof w);
fa[fx] = fy;
}
return;
}
int main() {
scanf("%d%d", &n, &m);
for(int i = 1; i <= n; ++i) fa[i] = i;
int opt, a, b;
while(m--) {
scanf("%d%d%d", &opt, &a, &b);
if(opt == 1) Merg(a, b);
else w[Find(a)] += b;
}
for(int i = 1; i <= n; ++i) printf("%d%c", res[i]+w[Find(i)], i==n?'\n':' ');
return 0;
}