2018 China Collegiate Programming Contest Final (CCPC-Final 2018)(A B G I L)
A:签到题,正常模拟即可。
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e5 + ;
struct node{
int id, time;
};
node a[maxn];
bool cmp(const node &a, const node &b){
if(a.id^b.id) return a.id < b.id;
else return a.time < b.time;
}
int main()
{
std::ios::sync_with_stdio(false);
int n, m, t;
cin >> t;
for(int cas = ;cas <= t;cas++)
{
cin >> n >> m;
for(int i = ;i < n;i++) cin >> a[i].id;
for(int i = ;i < n;i++) cin >> a[i].time;
int ans = ;sort(a, a + n, cmp);
int sum = ;
for(int i = ;i < n;i++)
{
if(sum + a[i].time <= m) sum += a[i].time, ans ++;
else break;
}
cout << "Case " << cas << ": ";
cout<< ans << endl;
}
return ;
}
B:对于差值尽量小的问题,可以采用枚举最小值,然后使得最大值尽量小。
首先二分图判定,然后分块,求出每块的光明状态的最大最小值,黑暗状态的最大最小值,然后按分块编号塞到线段树离维护最大值,然后对这2*cnt个块由最小值从小到大进行排序,枚举每个块的最小值,然后更新答案,然后将这个块的最大值在线段树中删去,当某个块的光明状态和黑暗状态都被删去的时候,就不用继续枚举了。
#include<bits/stdc++.h>
#define ls rt << 1
#define rs rt << 1 | 1
#define lr2 (l + r) >> 1
#define lson l, mid, rt << 1
#define rson mid + 1, r, rt << 1 | 1
using namespace std;
typedef long long ll;
const int maxn = 5e5 + ;
const int INF = 0x3f3f3f3f;
struct node{
int maxx, minn, id;
bool operator <(const node &b)const{
return minn < b.minn;
}
};
struct tree{
pair<int, int> p[];
int val;
void deleted(int x)
{
if(p[].first == x) p[].second = INF;
else p[].second = INF;
}
};
int n, m, t;
vector<int> G[maxn];
int L[maxn], D[maxn];
int color[maxn] , vis[maxn], cnt;
tree T[maxn << ];
node A[maxn];
bool flag;
int num[maxn];
void pushup(int rt)
{
T[rt].val = max(T[ls].val, T[rs].val);
}
void build(int l, int r, int rt)
{
if(l == r)
{
T[rt].p[] = {A[l].minn, A[l].maxx};
T[rt].p[] = {A[l + cnt].minn, A[l + cnt].maxx};
T[rt].val = min(A[l].maxx, A[l + cnt].maxx);
return;
}
int mid = lr2;
build(lson);
build(rson);
pushup(rt);
}
void update(int k, int v, int l, int r, int rt){
if(l == r){
T[rt].deleted(v);
T[rt].val = min(T[rt].p[].second, T[rt].p[].second);
return;
}
int mid = lr2;
if(k <= mid) update(k, v, lson);
else update(k, v ,rson);
pushup(rt);
}
bool dfs(int v, int c, int id){
color[v] = c;
vis[v] = id;
for(int i = ;i < G[v].size();i++)
{
int u = G[v][i];
if(color[u] == c) return false;
if(!color[u]){
if(!dfs(u, - c, id)) return false;
}
}
return true;
}
void init()
{
for(int i = ;i <= n;i++) G[i].clear();
fill(color, color + n + , );
fill(vis, vis + n + , );
fill(num, num + n + , );
cnt = ;flag = false;
}
int main()
{
std::ios::sync_with_stdio(false);
cin >> t;
for(int cas = ; cas <= t;cas++)
{
cin >> n >> m;
init();
for(int i = ;i < m;i++)
{
int a, b; cin >> a >> b;
G[a].push_back(b);
G[b].push_back(a);
}
for(int i = ;i <= n;i++) cin >> L[i] >> D[i];
for(int i = ;i <= n;i++)
{
if(!vis[i])
{
++cnt;
if(!dfs(i, , cnt))
{
flag = true;
break;
}
}
}
cout << "Case " << cas << ": ";
if(flag){
cout << "IMPOSSIBLE" << endl;
continue;
}
for(int i = ;i <= * cnt;i++)
{
A[i].maxx = , A[i].minn = INF;
}
for(int i = ;i <= n;i++){
int x = vis[i];
if(color[i] == )
{
A[x].id = x;
A[x].maxx = max(A[x].maxx, L[i]);
A[x].minn = min(A[x].minn, L[i]);
A[x + cnt].id = x;
A[x + cnt].maxx = max(A[x + cnt].maxx, D[i]);
A[x + cnt].minn = min(A[x + cnt].minn, D[i]);
}
else{
A[x].id = x;
A[x].maxx = max(A[x].maxx, D[i]);
A[x].minn = min(A[x].minn, D[i]);
A[x + cnt].id = x;
A[x + cnt].maxx = max(A[x + cnt].maxx, L[i]);
A[x + cnt].minn = min(A[x + cnt].minn, L[i]);
}
}
build(, cnt, );
sort(A + , A + * cnt + );
int ans = INF;
for(int i = ;i <= * cnt;i++)
{
ans = min(ans, T[].val - A[i].minn);
num[A[i].id]++;
if(num[A[i].id] == ) break;
update(A[i].id, A[i].minn, , cnt, );
}
cout << ans << endl;
}
return ;
}
G:题目大意:在一个n * m的土地,要在一个子矩形内放稻草人,稻草人必须被稻草包围,问合法的方法有多少种?
问题其实可以转化为:在n * m的草地上,选出一块子矩形,这个子矩形来放满稻草人必须被包括在n * m的矩形内。可以行和列分开考虑,(行的方案数) * (列的方案数)就是答案。一行可以选4个点,里面两个点是子矩形的宽的边界(列的边界),发现这样能确定一个子矩形的列的情况,但还有一种遗漏,就是只有一列的子矩形,这种情况只需要选三个点,所以是c[m][3] + c[m][4], 这样就确定了列的所有方案,行的方案跟列的方案类似。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e5 + ;
const int mod = 1e9 + ;
ll C[maxn][];
void init()
{
C[][] = ;
for(int i = ; i <= maxn;i++)
{
C[i][] = ;
for(int j = ; j <= ;j++)
C[i][j] = (C[i - ][j] + C[i - ][j - ]) % mod;
}
}
int main()
{
std::ios::sync_with_stdio(false);
int n, m ,t;
cin >> t;
init();
for(int cas = ;cas <= t;cas++)
{
cin >> n >> m;
ll h = (C[n][] + C[n][]) % mod;
ll w = (C[m][] + C[m][]) % mod;
ll ans = h * w % mod;
cout << "Case "<< cas << ": ";
cout << ans << endl;
}
return ;
}
I:记录每个点的横纵坐标所在行列的点的数目,找到最大的maxx,maxy,max_x = maxx+maxy,其实消灭蟑螂的最大数目只能是max_x,或者max_x-1。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e5 + ;
ll n;
map<int,int> x, y;
struct node{
int x,y;
};
node a[maxn];
int main()
{
std::ios::sync_with_stdio(false);
int t;
cin >> t;
for(int cas = ; cas <=t; cas++){
cin >> n;
x.clear();
y.clear();
for(int i = ; i <= n; i++){
cin >> a[i].x >> a[i].y;
x[a[i].x]++;
y[a[i].y]++;
}
int maxx = , maxy = ;
for(int i = ; i <= n; i++){
maxx = max(maxx, x[a[i].x]);
maxy = max(maxy, y[a[i].y]);
}
if(x.size() == || y.size() == ){
cout << "Case " << cas << ": " << n << " " << << endl;
}
else{
if(maxx == && maxy == ){
cout << "Case " << cas << ": " << << " " << n*(n-)/ << endl;
}
else{
ll x1 = , x2 = , y1 = , y2 = ;
map<int,int>::iterator it;
for(it = x.begin(); it != x.end(); it++){
if(it->second == maxx) x1++;
else if(it->second == maxx - ) x2++;
}
for(it = y.begin(); it != y.end(); it++){
if(it->second == maxy) y1++;
else if(it->second == maxy - ) y2++;
}
ll ans1 = , ans2 = ;
ans1 = x1 * y1;
ans2 = x2 * y1 + x1 * y2;
for(int i = ; i <= n; i++){
if(maxx + maxy == x[a[i].x] + y[a[i].y]){
ans1--;
ans2++;
}
else if(maxx + maxy - == x[a[i].x] + y[a[i].y]){
ans2--;
}
}
if(ans1){
cout << "Case " << cas << ": " << maxx + maxy << " " << ans1 << endl;
}
else{
cout << "Case " << cas << ": " << maxx + maxy - << " " << ans2 << endl;
}
}
}
} }
L:贪心 + 分类讨论 + 暴力。小于等于11直接impossible, 然后奇数可以拆成 2 2 2 3 + 偶数, 偶数可以拆成2 2 2 2 + 偶数,对最后的偶数暴力分解即可。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
bool check(ll x)
{
int n = sqrt(x);
for(int i = ;i <= n;i++){
if(x % i == )return false;
}
return true; }
void print(ll n)
{
for(ll i = n - ;i >= ;i--){
if(check(i) && check(n - i)){
cout << " " << i << " " << n - i << endl;
return;
}
}
}
int main()
{
std::ios::sync_with_stdio(false);
int t;
cin >> t;
int cnt = ;
while(t--)
{
ll n;
cin >> n;
cout << "Case "<< cnt++ <<": ";
if(n > )
{
if(n & )
{
n -= 9LL;
cout << "2 2 2 3";
print(n);
}
else{
n -= 8LL;
cout << "2 2 2 2";
print(n);
}
}
else cout << "IMPOSSIBLE" << endl;
}
return ;
}
2018 China Collegiate Programming Contest Final (CCPC-Final 2018)(A B G I L)的更多相关文章
- 2018 China Collegiate Programming Contest Final (CCPC-Final 2018)-K - Mr. Panda and Kakin-中国剩余定理+同余定理
2018 China Collegiate Programming Contest Final (CCPC-Final 2018)-K - Mr. Panda and Kakin-中国剩余定理+同余定 ...
- 2018 China Collegiate Programming Contest Final (CCPC-Final 2018)
Problem A. Mischievous Problem Setter 签到. #include <bits/stdc++.h> using namespace std; #defin ...
- 模拟赛小结:2018 China Collegiate Programming Contest Final (CCPC-Final 2018)
比赛链接:传送门 跌跌撞撞6题摸银. 封榜后两题,把手上的题做完了还算舒服.就是罚时有点高. 开出了一道奇奇怪怪的题(K),然后ccpcf银应该比区域赛银要难吧,反正很开心qwq. Problem A ...
- 2016 China Collegiate Programming Contest Final
2016 China Collegiate Programming Contest Final Table of Contents 2016 China Collegiate Programming ...
- The 2015 China Collegiate Programming Contest A. Secrete Master Plan hdu5540
Secrete Master Plan Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 65535/65535 K (Java/Othe ...
- The 2015 China Collegiate Programming Contest Game Rooms
Game Rooms Time Limit: 4000/4000MS (Java/Others) Memory Limit: 65535/65535KB (Java/Others) Submi ...
- 2018 German Collegiate Programming Contest (GCPC 18)
2018 German Collegiate Programming Contest (GCPC 18) Attack on Alpha-Zet 建树,求lca 代码: #include <al ...
- (寒假GYM开黑)2018 German Collegiate Programming Contest (GCPC 18)
layout: post title: 2018 German Collegiate Programming Contest (GCPC 18) author: "luowentaoaa&q ...
- 2017 China Collegiate Programming Contest Final (CCPC 2017)
题解右转队伍wiki https://acm.ecnu.edu.cn/wiki/index.php?title=2017_China_Collegiate_Programming_Contest_Fi ...
随机推荐
- node进程一些信号的意义
1.SIGINT这个信号是系统默认信号,代表信号中断,就是ctrl+c: 2.SIGQUIT 3.SIGTERM 4.exit
- [Codeforces 997C]Sky Full of Stars(排列组合+容斥原理)
[Codeforces 997C]Sky Full of Stars(排列组合+容斥原理) 题面 用3种颜色对\(n×n\)的格子染色,问至少有一行或一列只有一种颜色的方案数.\((n≤10^6)\) ...
- Python自学第一天
Python #-*- coding:utf8 -*-(Python文件开头添加)用来解决中文编码问题 注:Python3以上文件不用加 一.变量:变量有数字.字母和下划线组成 1.不能以数字开头 2 ...
- 阿里云ECS服务安装 nginx+php+MariaDB完整版
安装 Nginx想在 CentOS 系统上安装 Nginx ,你得先去添加一个资源库,像这样: vim /etc/yum.repos.d/nginx.repo使用 vim 命令去打开 /etc/yum ...
- Zookeeper之启动常见错误及解决方法
Zookeeper启动后,有时候没有真正的启动,那我们如何查找错误呢,就可以查看zookeeper目录下面的zookeeper.out文件,就可以查看到错误了.zookeeper.out文件比较的重要 ...
- bounds与frame的区别及setBounds的使用
转自http://www.cocoachina.com/ios/20140925/9755.html 在iOS开发中经常遇到两个词Frame和bounds,本文主要阐述Frame和bound的区别,尤 ...
- mysql03--误删除了所有用户解决办法
误删除了所有用户解决办法 第一种方法(企业常用) 1.将数据库down掉 [root@db03 mysql]# /etc/init.d/mysqld stop Shutting down MySQL. ...
- LeetCode(力扣)——Search in Rotated Sorted Array2 搜索旋转排序数组 python实现
题目描述: python实现 Search in Rotated Sorted Array2 搜索旋转排序数组 中文: 假设按照升序排序的数组在预先未知的某个点上进行了旋转. ( 例如,数组 [0 ...
- C++链接器
链接器把多个二进制的目标文件(object file)链接成一个单独的可执行文件 在链接过程中,它必须把符号(变量名.函数名等一些列标识符)用对应的数据的内存地址(变量地址.函数地址等)替代,以完成程 ...
- apache2 配置入门
ServerRoot "/usr/local/apache2" #服务器根目录 Listen #监听端口 语法格式为Listen [IP地址:]端口 [协议],其中IP地址与协议为 ...