当前位置: 代码迷 >> 综合 >> Codeforces Round #541 (Div. 2) codeforces.com/1131
  详细解决方案

Codeforces Round #541 (Div. 2) codeforces.com/1131

热度:87   发布时间:2023-12-12 17:37:39.0

题目链接:https://codeforces.com/contest/1131

目录

A

B

C

D

E

F

 


A Sea Battle

题意没仔细读,看了样例猜了一下意思就写了,大概就是两个相邻的矩形然后求一下他们周围的面积是多少,考虑单独两个图形周围面积,减去图形的,然后再合并,合并会删除两行的面积,减去就可以了(画一下图,很容易出来)

代码:

#include <bits/stdc++.h>
#include <time.h>
using namespace std;typedef long long ll;
typedef pair<int,int>  P;
const int maxn = 2e6 + 5000;
//queue<pair<string,int> >q;
const ll mod = 1e9 + 7;
ll mul(ll a,ll b,ll c) {ll res = 1;while(b) {if(b & 1) res *= a,res %= c;a *= a,a %= c,b >>= 1;}return res;
}
ll phi(ll x) {ll res = x;for(ll i = 2; i * i <= x; i++) {if(x % i == 0) res = x / i * (i - 1);while(x % i == 0) x /= i;}if(x > 1) res = res / x  * (x - 1);return res;
}
struct node {int x, y;node(int x=0, int y=0):x(x),y(y) {}bool operator < (const node &b) const {
//           if(x > b.x) return 1;
//           else if(x == b.x)
//                 if(y >= b.y) return 1;
//           return 0;}
};
ll n,t,m,k;
int main() {ios::sync_with_stdio(false);struct node g;ll w1,w2,h1,h2;while(cin >> w1 >> h1 >> w2 >> h2 ) {ll s1 = (w1 + 2) * (h1 + 2) - w1 * h1;ll s2 = (w2 + 2) * (h2 + 2) - w2 * h2;cout << s1 + s2 - (min(w1,w2) + 2) * 2 << endl;}//cout << "time: " << (long long)clock() * 1000 / CLOCKS_PER_SEC << " ms" << endl;return 0;
}

B Draw!

  告诉你一些分数,问你平局的最多次数

  每次取一下min,比较一下,计数ans即可

代码如下:


#include <bits/stdc++.h>
#include <time.h>
using namespace std;typedef long long ll;
typedef pair<int,int>  P;
const int maxn = 2e6 + 5000;
//queue<pair<string,int> >q;
const ll mod = 1e9 + 7;
ll mul(ll a,ll b,ll c) {ll res = 1;while(b) {if(b & 1) res *= a,res %= c;a *= a,a %= c,b >>= 1;}return res;
}
ll phi(ll x) {ll res = x;for(ll i = 2; i * i <= x; i++) {if(x % i == 0) res = x / i * (i - 1);while(x % i == 0) x /= i;}if(x > 1) res = res / x  * (x - 1);return res;
}
struct node {int x, y;node(int x=0, int y=0):x(x),y(y) {}bool operator < (const node &b) const {
//           if(x > b.x) return 1;
//           else if(x == b.x)
//                 if(y >= b.y) return 1;
//           return 0;}
};
ll n,t,k;
map<int,int>m;
ll a[maxn];
ll b[maxn];
set<int>s;
vector<int>v;
int main() {ios::sync_with_stdio(false);struct node g;ll w1,w2,h1,h2;while(cin >> n) {for(int i = 1; i<= n; i++) cin >> a[i] >>b[i] ,m[a[i]]++,s.insert(a[i]);ll ans = 1ll;for(int i = 1; i <= n; i++) {if(min(a[i],b[i]) >= a[i - 1] && min(a[i],b[i]) >= b[i - 1])       ans += min(a[i], b[i]) - max(a[i - 1], b[i - 1]) + 1;ans++; if(a[i - 1] == b[i - 1]) ans--;ans--;}cout <<ans <<endl;}//cout << "time: " << (long long)clock() * 1000 / CLOCKS_PER_SEC << " ms" << endl;return 0;
}

C Birthday

给你n个数,要求任意排列,差值最小

贪心,排序一下,两头放即可保证最小

#include <bits/stdc++.h>
#include <time.h>
using namespace std;typedef long long ll;
typedef pair<int,int>  P;
const int maxn = 2e6 + 5000;
//queue<pair<string,int> >q;
const ll mod = 1e9 + 7; 
ll n,t,k;
map<int,int>m;
ll a[maxn];
set<int>s;
deque<int>q;
vector<int>v;
int main() {ios::sync_with_stdio(false);while(cin >> n) {for(int i = 1; i<= n; i++) cin >> a[i],m[a[i]]++,v.push_back(a[i]);sort(a + 1,a + 1 + n);if(n <= 3) {for(int i = 1;i <= n;i++){cout <<a[i] << " ";}cout <<endl; continue;}int flag = 0;for(int i = 1; i <= n; i++) {if(!flag)q.push_front(a[i]),flag = 1;else q.push_back(a[i]),flag = 0;}while(!q.empty()) {cout <<q.front() <<" ";q.pop_front();}}//cout << "time: " << (long long)clock() * 1000 / CLOCKS_PER_SEC << " ms" << endl;return 0;
}

D Gourmet choice

有两个正整数序列 a,,b,给出所有 ai 和 bj的大小关系(大于,小于或者等于),请构造出符合条件的 a 和 b。如果无解,输出NO。如果有多个解,输出 a,,b 中最大元素最小的方案。

思路首先你可以针对两个数之间的大于小于关系建图,相等的时候,并查集合并、缩点,从小于的点开始往大于的点跑一遍拓扑排序,然后再遇到边的时候考虑转移 + 1就可以了

还有就是什么时候考虑NO的情况,显然如果拓扑的时候在大小关系中出现了环,则证明不可能构造出这样的两个序列

代码如下:

#include <bits/stdc++.h>
#include <time.h>
using namespace std;typedef long long ll;
typedef pair<int,int>  P;
const int maxn = 2e3 + 5000;
const ll mod = 1e9 + 7;
ll t,k,n,m;
char str[maxn][maxn];
int fa[maxn];
int Find(int x) {if(x == fa[x])return x;return fa[x] = Find(fa[x]);
}
vector<vector<int> >v;
int ans[maxn];
int rvis[maxn];
int main() {ios::sync_with_stdio(false);while(cin >> n >> m) {v.resize(maxn);memset(rvis,0,sizeof(rvis));for(int i = 1; i < maxn; i++) fa[i] = i;for(int i = 1; i <= n; i++) cin >> str[i] + 1;for(int i = 1; i <= n; i++)for(int j = 1; j <= m; j++) {if (str[i][j] == '=')  fa[Find(i)] = Find(n + j);}for(int i = 1; i <= n; i++) {for(int j = 1; j <= m; j++) {if (str[i][j] == '<')       v[Find(i)].push_back(Find(j + n)),rvis[Find(j + n)]++;else if (str[i][j] == '>')  v[Find(j + n)].push_back(Find(i)),rvis[Find(i)]++;}}queue<int>q;int cnt = 0,num = 0;for(int i = 1; i <= n + m; i++) {if(Find(i) == i) {if(!rvis[i])q.push(i),ans[i] = 1; }}while(!q.empty()) { num++;int x = q.front();q.pop();for(auto d:v[x]) {ans[d] = max(ans[d],ans[x] + 1);rvis[d]--;if(!rvis[d])q.push(d);}}if(num != cnt) {cout << "NO" << endl;continue;}cout << "YES" << endl;for(int i = 1; i <= n; i++)cout << ans[Find(i)] << " ";cout << endl;for(int i = n + 1; i <= n + m; i++)cout <<  ans[fa[i]]  << " ";cout << endl;}return 0;
}

E String Multiplication

先放代码吧 明天写(考虑前缀 后缀 、 以及中间存在的连续的最长子串) , 然后再想怎么转移

#include <bits/stdc++.h>
#include <time.h>
using namespace std;typedef long long ll;
typedef pair<int,int>  P;
const int maxn = 2e6 + 5000;
const ll mod = 1e9 + 7;
ll t,k,n,m;
string str;
int pre[27];
int post[27];
int in[27];
void calc() {memset(pre,0,sizeof(pre));memset(post,0,sizeof(post));memset(in,0,sizeof(in));for(int i = 0; i < 26; i++) {for(int j = 0; j < str.size(); j++) {if(str[j] == i + 'a') pre[i] = pre[i] + 1;else break;}for(int j = str.size() - 1; j >= 0; j--) {if(str[j] == i + 'a') post[i] = post[i] + 1;else break;}int num = 0;for(int j = 0; j < str.size(); j++) {if(str[j] == 'a' + i) num++;else  num = 0;in[i] = max(num,in[i]);}}
}
int f[30][maxn];
int main() {ios::sync_with_stdio(false);while(cin >> n) {cin >> str;calc();for(int i = 0; i < 26; i++) f[i][0] = in[i];for(int i = 1; i < n; i++) {cin >> str;calc();for(int j = 0; j < 26; j++) {if(f[j][i - 1])f[j][i] = 1;}for(int j = 0;j < 26; j++){if(f[j][i - 1]){if(pre[j] == str.size()) f[j][i] = str.size() * (f[j][i - 1] + 1) + f[j][i - 1];else f[j][i] = post[j] + pre[j] + 1;}}for(int j = 0;j < 26;j++){f[j][i] = max(f[j][i],in[j]);}}int ans = 0;for(int j = 0;j < 26;j++) ans = max(ans,f[j][n - 1]);cout << ans << endl;}return 0;
}

F Asya And Kittens

先放代码吧 明天写 (考虑并查集合并,没写链表合并,直接暴力一个vector)

#include <bits/stdc++.h>
#include <time.h>
using namespace std;typedef long long ll;
typedef pair<int,int>  P;
const int maxn = 2e6 + 5000;
//queue<pair<string,int> >q;
const ll mod = 1e9 + 7;
ll mul(ll a,ll b,ll c) {ll res = 1;while(b) {if(b & 1) res *= a,res %= c;a *= a,a %= c,b >>= 1;}return res;
}
ll phi(ll x) {ll res = x;for(ll i = 2; i * i <= x; i++) {if(x % i == 0) res = x / i * (i - 1);while(x % i == 0) x /= i;}if(x > 1) res = res / x  * (x - 1);return res;
}
struct node {int x, y;node(int x=0, int y=0):x(x),y(y) {}bool operator < (const node &b) const {
//           if(x > b.x) return 1;
//           else if(x == b.x)
//                 if(y >= b.y) return 1;
//           return 0;}
};
ll t,k;vector<int>v[maxn];
int fa[maxn];
int Find(int x) {if(x ==fa[x]) {return x;}return fa[x] = Find(fa[x]);
}
int n,a,b;
void Init() {for(int i = 1 ; i <= n+ 5; i++)fa[i]=i;return ;
}
int main() {while(cin >> n) {Init();for(int i = 1; i < n; i++) {cin >> a >> b;int X = Find(a);int Y = Find(b);if(X != Y) {if(v[X].size() > v[Y].size()) {v[X].push_back(Y);for(int j = 0; j < v[Y].size(); j++)  v[X].push_back(v[Y][j]);fa[Y] = X; } else {v[Y].push_back(X);for(int j = 0; j < v[X].size(); j++)   v[Y].push_back(v[X][j]);fa[X]=Y;}}}for(int i = 1; i <= n; i++) {if(fa[i] == i) {cout << i;for(int j = 0; j < v[i].size(); j++)cout << " " << v[i][j];cout << endl;return 0 ;}}}return 0;
}

 

 

 

 

  相关解决方案