网址:https://ac.nowcoder.com/acm/contest/4370
B. Prefix Code
阅读理解,用个set维护下就行
#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 ls u<<1
#define rs u<<1|1
#define rep(i,a,n) for(int i=a;i<=n;i++)
#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<ll, ll > 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;
string s, t;
set<string>s1, s2;
vector<string>vec;
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
int cas = 0;
_ = read();
while (_--) {
s1.clear();
s2.clear();
vec.clear();
n = read();
bool f = 1;
rep(i, 1, n) {
cin >> s;
if (s1.find(s) != s1.end()) f = 0;
s1.insert(s);
vec.push_back(s);
}
rep(i, 0, n - 1) {
s = vec[i];
t.clear();
for (int i = 0; i < s.size() - 1; ++i) {
t += s[i];
if (s1.find(t) != s1.end()) {
f = 0;
break;
}
if (!f) break;
}
if (!f) break;
}
printf("Case #%d: ", ++cas);
if (f) puts("Yes");
else puts("No");
}
// #ifndef ONLINE_JUDGE
// system("pause");
// #endif
}
K. Color Graph
二分图签到
题意可以转化为判奇环,可以发现n很小,二进制枚举每个点的状态,然后直接判断即可
#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 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 pair<int, int > PII;
priority_queue< PII, vector<PII>, greater<PII> > que;
stringstream ssin; // ssin << string while ( ssin >> int)
const int N = 500, mod = 1e9 + 9, INF = 0x3f3f3f3f;
int t, n, m, idx, id, pos, Max;
int e[N], h[N], ne[N], col[20];
bool flag;
inline int read(){
char c=getchar();int 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 a, int b) {
e[idx] = b;
ne[idx] = h[a];
h[a] = idx++;
}
vector<PII> vec;
int main()
{
cin >> t;
while (t--) {
vec.clear();
Max = -1;
mm(h, -1);
idx = 0;
cin >> n >> m;
for (int i = 1; i <= m; ++i) {
int a, b;
cin >> a >> b;
vec.push_back(mp(a, b));
}
for (pos = 0; pos <= (1 << n); ++pos) {
mm(col, 0);
flag = 1;
for (int i = 1; i <= n; ++i) {
if ((pos >> i) & 1 && !col[i]) {
col[i] = 1;
}
}
int ans = 0;
for (int i = 0; i < vec.size(); ++i) {
int x = vec[i].first, y = vec[i].second;
if (col[x] != col[y]) ans++;
}
Max = max(Max, ans);
}
printf("Case #%d: %d\n", ++id, Max);
}
// system("pause");
return 0;
}
E. Cave Escape
可以发现起点和终点并不影响选择的路径,所以只需要对点建边求最大生成树即可
#pragma GCC optimize(2)
#include<bits/stdc++.h>
using namespace std;
const int man = 1e3+10;
#define IOS ios::sync_with_stdio(0)
template <typename T>
inline T read(){T sum=0,fl=1;int ch=getchar();
for(;!isdigit(ch);ch=getchar())if(ch=='-')fl=-1;
for(;isdigit(ch);ch=getchar())sum=sum*10+ch-'0';
return sum*fl;}
template <typename T>
inline void write(T x) {static int sta[35];int top=0;
do{sta[top++]= x % 10, x /= 10;}while(x);
while (top) putchar(sta[--top] + 48);}
template<typename T>T gcd(T a, T b) {return b==0?a:gcd(b, a%b);}
template<typename T>T exgcd(T a,T b,T &g,T &x,T &y){if(!b){g = a,x = 1,y = 0;}
else {exgcd(b,a%b,g,y,x);y -= x*(a/b);}}
#ifndef ONLINE_JUDGE
#define debug(fmt, ...) {printf("debug ");printf(fmt,##__VA_ARGS__);puts("");}
#else
#define debug(fmt, ...)
#endif
typedef long long ll;
const ll mod = 1e9+7;
int x[man*man],fa[man*man],va[man][man];
int sz[man*man];
vector<pair<int,int> >A[10010];
int find(int x){
return x == fa[x] ? x : fa[x] = find(fa[x]);
}
/*
int find(int x){
int p = x;
while(p!=fa[p])p = fa[p];
while(x!=p){
int tp = fa[x];
fa[x] = p;
x = tp;
}
return p;
}*/
bool _union(int u,int v){
// cout << u << " 1\" " << v <<endl;
u = find(u);
v = find(v);
// cout << u << " 2\" " << v << endl;
if(u==v)return true;
if(sz[u]>sz[v]){
sz[u] += sz[v];
fa[v] = u;
}else fa[u] = v,sz[v] += sz[u];
return false;
}
int main() {
#ifndef ONLINE_JUDGE
//freopen("in.txt", "r", stdin);
//freopen("out.txt","w",stdout);
#endif
int t;
scanf("%d",&t);
int T = 0;
while(t--){
int n,m,s,a,b,c,p;
for(int i = 0;i <= 10000;i++)A[i].clear();
scanf("%d%d%d%d%d%d",&n,&m,&s,&s,&s,&s);
scanf("%d%d%d%d%d%d",x+1,x+2,&a,&b,&c,&p);
fa[1] = 1;
fa[2] = 2;
for(int i = 3;i <= n*m;i++){
fa[i] = i;
sz[i] = 1;
x[i] = (a*x[i-1] + b*x[i-2] + c)%p;
}
int cnt = 0;
for(int i = 1;i <= n;i++){
for(int j = 1;j <= m;j++){
va[i][j] = x[(i-1)*m + j];
if(!va[i][j])continue;
if(i>1&&va[i-1][j])A[va[i][j]*va[i-1][j]].push_back(make_pair((i-1)*m + j,(i-2)*m + j));
if(j>1&&va[i][j-1])A[va[i][j]*va[i][j-1]].push_back(make_pair((i-1)*m + j,(i-1)*m + j - 1));
}
}
ll ans = 0;
int res = 0;
for(int j = 10000;j >= 0;j--){
for(int i = 0;i < A[j].size();i++){
int u = A[j][i].first;
int v = A[j][i].second;
//cout << A[i].w << endl;
// if(!_union(u,v)){
// }
if (find(u) == find(v)) continue;
int pa = find(u), pb = find(v);
fa[pa] = pb;
ans += j;
res++;
if(res==n*m-1)break;
}
if(res==n*m-1)break;
}
printf("Case #%d: %lld\n",++T,ans);
}
return 0;
}
H. Tree Partition
二分+贪心
对于每棵树一定是去掉最大的子树最优
#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 ls u<<1
#define rs u<<1|1
#define rep(i,a,n) for(int i=a;i<=n;i++)
#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<ll, ll > 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, k, idx;
int e[M], ne[M], h[N];
int flag, cnt;
ll sum[N], a[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 a, int b) {
e[idx] = b;
ne[idx] = h[a];
h[a] = idx++;
}
void dfs(int u, int fa, ll mid) {
sum[u] = a[u];
if (sum[u] > mid || flag) {
flag = 1;
return;
}
for (int i = h[u]; ~i; i = ne[i]) {
int v = e[i];
if (v == fa) continue;
dfs(v, u, mid);
sum[u] += sum[v];
}
if (sum[u] > mid) {
vector<ll>vec;
for (int i = h[u]; ~i; i = ne[i]) {
int v = e[i];
if (v == fa) continue;
vec.push_back(sum[v]);
}
sort(vec.begin(), vec.end());
for (int i = vec.size() - 1; i >= 0; --i) {
if (sum[u] <= mid) break;
sum[u] -= vec[i];
cnt++;
}
}
if (cnt > k - 1) {
flag = 1;
}
}
bool ck(ll mid) {
cnt = flag = 0;
dfs(1, -1, mid);
if (flag) return false;
return true;
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
#endif
_ = read();
ll cas = 0, ans;
while (_--) {
n = read(); k = read();
idx = 0;
for (int i = 0; i <= n; ++i) h[i] = -1;
rep(i, 1, n - 1) {
int u, v;
u = read(); v = read();
add(u, v);
add(v, u);
}
rep(i, 1, n) a[i] = read();
ll l = 0ll, r = 1e14;
while (l < r) {
ll mid = l + r >> 1;
if (ck(mid)) {
r = mid;
ans = mid;
} else {
l = mid + 1;
}
}
printf("Case #%lld: %lld\n", ++cas, l);
}
// #ifndef ONLINE_JUDGE
// system("pause");
// #endif
}
D. Spanning Tree Removal
构造,对于每棵树 i,i + 1, i - 1, i + 2, i - 2, i + 3, i - 2......
#include <stdio.h>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
#include <map>
#include <stack>
#include <sstream>
#include <set>
// #include <unordered_set>
// #pragma GCC optimize(2)
//#define int long long
#define ls u<<1
#define rs u<<1|1
#define rep(i,a,n) for(int i=a;i<=n;i++)
#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<ll, ll > PII;
priority_queue< PII, vector<PII>, greater<PII> > que;
stringstream ssin; // ssin << string while ( ssin >> int)
const ll LINF = 0x7fffffffffffffffll;
const int N = 1e3 + 5, M = 4e5 + 5, mod = 1e9 + 7, INF = 0x3f3f3f3f;
int _, n;
vector<PII>vec;
bool vis[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
int cas = 0;
_ = read();
while (_--) {
n = read();
printf("Case #%d: %d\n", ++cas, n / 2);
rep(i, 1, n / 2) {
int now = i - 1;
printf("%d %d\n", now % n + 1, (now + 1) % n + 1);
for (int j = 2; j <= n - 1; ++j) {
if (j & 1) printf("%d %d\n", (now - j / 2 + n) % n + 1, (now + j / 2 + 1) % n + 1);
else printf("%d %d\n", (now + j / 2) % n + 1, (now - j / 2 + n) % n + 1);
}
}
}
// #ifndef ONLINE_JUDGE
// system("pause");
// #endif
}
本文总结了算法竞赛中常见的几种题目类型及其解决方案,包括前缀码、二分图、最大生成树等,通过具体实例介绍了如何高效解决问题。

2475

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



