Codeforces Round #683 (Div. 2, by Meet IT)
A - Add Candies solved
发现只要进行n次增加,第i次增加时选择第i个数即可
#include <stdio.h>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
#include <map>
#include <stack>
#include <sstream>
#include <set>
// #pragma GCC optimize(2)
//#define int long long
#define rep(i,a,n) for(int i=a;i<=n;i++)
#define rush() int T;scanf("%d",&T);for(int Ti=1;Ti<=T;++Ti)
#define IOS ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
#define mm(i,v) memset(i,v,sizeof i);
#define mp(a, b) make_pair(a, b)
#define pi acos(-1)
#define fi first
#define se second
using namespace std;
typedef long long ll;
typedef double db;
typedef pair<int, int > PII;
priority_queue< PII, vector<PII>, greater<PII> > que;
stringstream ssin; // ssin << string while ( ssin >> int)
const ll LINF = 0x7fffffffffffffffll;
const int N = 4e5 + 5, M = 4e5 + 5, mod = 1e9 + 7, INF = 0x3f3f3f3f;
int _, n;
inline ll read() {
char c=getchar();ll x=0,f=1;
while(c<'0'||c>'9'){if(c=='-')f=-1; c=getchar();}
while(c>='0'&&c<='9'){x=x*10+c-'0'; c=getchar();}
return x*f;
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
#endif
_ = read();
while (_--) {
n = read();
cout << n << '\n';
rep(i, 1, n)
printf("%d%c", i, i == n ? '\n' : ' ');
}
// #ifndef ONLINE_JUDGE
// system("pause");
// #endif
}
B - Numbers Box solved
观察一下可以发现最终答案与奇偶性有关
#include <stdio.h>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
#include <map>
#include <stack>
#include <sstream>
#include <set>
// #pragma GCC optimize(2)
//#define int long long
#define rep(i,a,n) for(int i=a;i<=n;i++)
#define rush() int T;scanf("%d",&T);for(int Ti=1;Ti<=T;++Ti)
#define IOS ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
#define mm(i,v) memset(i,v,sizeof i);
#define mp(a, b) make_pair(a, b)
#define pi acos(-1)
#define fi first
#define se second
using namespace std;
typedef long long ll;
typedef double db;
typedef pair<int, int > PII;
priority_queue< PII, vector<PII>, greater<PII> > que;
stringstream ssin; // ssin << string while ( ssin >> int)
const ll LINF = 0x7fffffffffffffffll;
const int N = 210, M = 4e5 + 5, mod = 1e9 + 7, INF = 0x3f3f3f3f;
int n, m, _, Min;
int sum, cnt;
inline ll read() {
char c=getchar();ll x=0,f=1;
while(c<'0'||c>'9'){if(c=='-')f=-1; c=getchar();}
while(c>='0'&&c<='9'){x=x*10+c-'0'; c=getchar();}
return x*f;
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
#endif
_ = read();
while (_--) {
n = read(); m = read();
Min = INF;
int x;
sum = 0; cnt = 0;
rep(i, 1, n) {
rep(j, 1, m) {
x = read();
sum += abs(x);
Min = min(Min, abs(x));
if (x <= 0) {
cnt++;
}
}
}
if (cnt & 1) {
cout << sum - 2 * Min << '\n';
} else {
cout << sum << '\n';
}
}
// #ifndef ONLINE_JUDGE
// system("pause");
// #endif
}
C - Knapsack solved
先判断一下有没有元素在[w / 2, w]之间,如果有的话直接输出这一个数即可
如果没有,那么剩下的数值一定全是小于w / 2或者大于w的。我们不考虑大于w的数字。
将小于w/2的数字排序后,从大到小累加,当累加的值满足在区间[w / 2,w]就符合条件,若加完后值小于w/2就不符合。
证明:因为剩下的数字都小于w / 2,就不可能存在加上某个数后答案突然从一个小于w/2的值跃迁到超过w的值的情况
#include <stdio.h>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
#include <map>
#include <stack>
#include <sstream>
#include <set>
// #pragma GCC optimize(2)
//#define int long long
#define rep(i,a,n) for(int i=a;i<=n;i++)
#define rush() int T;scanf("%d",&T);for(int Ti=1;Ti<=T;++Ti)
#define IOS ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
#define mm(i,v) memset(i,v,sizeof i);
#define mp(a, b) make_pair(a, b)
#define pi acos(-1)
#define fi first
#define se second
using namespace std;
typedef long long ll;
typedef double db;
typedef pair<int, int > PII;
priority_queue< PII, vector<PII>, greater<PII> > que;
stringstream ssin; // ssin << string while ( ssin >> int)
const ll LINF = 0x7fffffffffffffffll;
const int N = 4e5 + 5, M = 4e5 + 5, mod = 1e9 + 7, INF = 0x3f3f3f3f;
ll _, n, W, up;
struct node {
int id;
ll val;
}a[N];
bool cmp(node a, node b) {
if (a.val != b.val) return a.val < b.val;
return a.id < b.id;
}
inline ll read() {
char c=getchar();ll x=0,f=1;
while(c<'0'||c>'9'){if(c=='-')f=-1; c=getchar();}
while(c>='0'&&c<='9'){x=x*10+c-'0'; c=getchar();}
return x*f;
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
#endif
_ = read();
while (_--) {
n = read(); W = read();
up = (W + 1) / 2;
rep(i, 1, n) {
a[i].val = read();
a[i].id = i;
}
int flag = 0;
rep(i, 1, n) {
if (a[i].val >= up && a[i].val <= W) {
flag = i;
break;
}
}
if (flag) {
cout << 1 << '\n';
cout << flag << '\n';
continue;
}
sort(a + 1, a + 1 + n, cmp);
int l = 1;
int r = -1;
for (int i = 1; i <= n; ++i) {
if (a[i].val > W) {
r = i - 1;
break;
}
}
if (!r) {
puts("-1");
continue;
}
flag = 0;
ll sum = 0;
if (r == -1) r = n;
for (int i = r; i >= 1; --i) {
sum += a[i].val;
if (sum >= up && sum <= W) {
flag = i;
break;
}
}
if (!flag) puts("-1");
else {
cout << r - flag + 1 << '\n';
for (int i = flag; i <= r; ++i) {
cout << a[i].id << " ";
}
puts("");
}
}
// #ifndef ONLINE_JUDGE
// system("pause");
// #endif
}
D - Catching Cheaters unsolved
考虑dp
可以推出状态转移为
a[i] == b[j] dp[i][j] = dp[i - 1][j - 1] + 2; (lcm值加一,同时距离加二,总贡献加2)
a[i] != b[j] dp[i][j] = max(dp[i][j - 1], dp[i - 1][j]) - 1 (lcm不变但是距离加以,总贡献减一)
#include <stdio.h>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
#include <map>
#include <stack>
#include <sstream>
#include <set>
// #pragma GCC optimize(2)
//#define int long long
#define rep(i,a,n) for(int i=a;i<=n;i++)
#define rush() int T;scanf("%d",&T);for(int Ti=1;Ti<=T;++Ti)
#define IOS ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
#define mm(i,v) memset(i,v,sizeof i);
#define mp(a, b) make_pair(a, b)
#define pi acos(-1)
#define fi first
#define se second
using namespace std;
typedef long long ll;
typedef double db;
typedef pair<int, int > PII;
priority_queue< PII, vector<PII>, greater<PII> > que;
stringstream ssin; // ssin << string while ( ssin >> int)
const ll LINF = 0x7fffffffffffffffll;
const int N = 5050, M = 4e5 + 5, mod = 1e9 + 7, INF = 0x3f3f3f3f;
int n, m, ans;
char a[N], b[N];
int dp[N][N];
inline ll read() {
char c=getchar();ll x=0,f=1;
while(c<'0'||c>'9'){if(c=='-')f=-1; c=getchar();}
while(c>='0'&&c<='9'){x=x*10+c-'0'; c=getchar();}
return x*f;
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
#endif
n = read(); m = read();
scanf("%s", a + 1);
scanf("%s", b + 1);
rep(i, 1, n)
rep(j, 1, m) {
if (a[i] == b[j]) {
dp[i][j] = dp[i - 1][j - 1] + 2;
// dp[i][j] = max(dp[i][j], dp[i - 1][j - 1] + 2);
} else {
dp[i][j] = max(0, max(dp[i - 1][j], dp[i][j - 1]) - 1);
// dp[i][j] = max(dp[i - 1][j] - 1, 0);
// dp[i][j] = max(dp[i][j - 1] - 1, 0);
}
ans = max(ans, dp[i][j]);
}
cout << ans << '\n';
// #ifndef ONLINE_JUDGE
// system("pause");
// #endif
}
E - Xor Tree unsolved
把每个数的二进制表示挂在字典树上找规律后直接跑dfs即可
#include <stdio.h>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
#include <map>
#include <stack>
#include <sstream>
#include <set>
// #pragma GCC optimize(2)
//#define int long long
#define rep(i,a,n) for(int i=a;i<=n;i++)
#define rush() int T;scanf("%d",&T);for(int Ti=1;Ti<=T;++Ti)
#define IOS ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
#define mm(i,v) memset(i,v,sizeof i);
#define mp(a, b) make_pair(a, b)
#define pi acos(-1)
#define fi first
#define se second
using namespace std;
typedef long long ll;
typedef double db;
typedef pair<int, int > PII;
priority_queue< PII, vector<PII>, greater<PII> > que;
stringstream ssin; // ssin << string while ( ssin >> int)
const ll LINF = 0x7fffffffffffffffll;
const int N = 6e6 + 5, M = 4e5 + 5, mod = 1e9 + 7, INF = 0x3f3f3f3f;
int n, idx, ans;
int a[N], tr[N][2], ed[N];
inline ll read() {
char c=getchar();ll x=0,f=1;
while(c<'0'||c>'9'){if(c=='-')f=-1; c=getchar();}
while(c>='0'&&c<='9'){x=x*10+c-'0'; c=getchar();}
return x*f;
}
void add(int x)
{
int now = 0;
for (int i = 30; i >= 0; i--)
{
int t = x>>i&1;
if (!tr[now][t]) tr[now][t] = ++idx;
now = tr[now][t];
}
ed[now] = 1;
}
void dfs(int u)
{
int ls = tr[u][0];
int rs = tr[u][1];
if (ls) dfs(ls);
if (rs) dfs(rs);
if (ls && rs && ed[ls] >= 2 && ed[rs] >= 2)
{
int t = min(ed[ls], ed[rs]) - 1;
ans += t;
ed[u] += ed[ls] + ed[rs] - t;
}
else
ed[u] += ed[ls] + ed[rs];
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
#endif
n = read();
rep(i, 1, n) {
a[i] = read();
add(a[i]);
}
dfs(0);
cout << ans << '\n';
// #ifndef ONLINE_JUDGE
// system("pause");
// #endif
}
本文分享了Codeforces Round #683 (Div. 2, by Meet IT)中各题的解题思路。A题进行n次增加,第i次选第i个数;B题答案与奇偶性有关;C题先判断元素范围,再排序累加;D题考虑dp推出状态转移;E题将数二进制表示挂字典树跑dfs。
700

被折叠的 条评论
为什么被折叠?



