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)的更多相关文章

  1. 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-中国剩余定理+同余定 ...

  2. 2018 China Collegiate Programming Contest Final (CCPC-Final 2018)

    Problem A. Mischievous Problem Setter 签到. #include <bits/stdc++.h> using namespace std; #defin ...

  3. 模拟赛小结:2018 China Collegiate Programming Contest Final (CCPC-Final 2018)

    比赛链接:传送门 跌跌撞撞6题摸银. 封榜后两题,把手上的题做完了还算舒服.就是罚时有点高. 开出了一道奇奇怪怪的题(K),然后ccpcf银应该比区域赛银要难吧,反正很开心qwq. Problem A ...

  4. 2016 China Collegiate Programming Contest Final

    2016 China Collegiate Programming Contest Final Table of Contents 2016 China Collegiate Programming ...

  5. 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 ...

  6. The 2015 China Collegiate Programming Contest Game Rooms

    Game Rooms Time Limit: 4000/4000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others) Submi ...

  7. 2018 German Collegiate Programming Contest (GCPC 18)

    2018 German Collegiate Programming Contest (GCPC 18) Attack on Alpha-Zet 建树,求lca 代码: #include <al ...

  8. (寒假GYM开黑)2018 German Collegiate Programming Contest (GCPC 18)

    layout: post title: 2018 German Collegiate Programming Contest (GCPC 18) author: "luowentaoaa&q ...

  9. 2017 China Collegiate Programming Contest Final (CCPC 2017)

    题解右转队伍wiki https://acm.ecnu.edu.cn/wiki/index.php?title=2017_China_Collegiate_Programming_Contest_Fi ...

随机推荐

  1. find命令之正则表达式

    find -regex '.*_\(OK\|NG\).csv'|sort // 特殊字符需要进行转义 for file in `find -regex '.*_\(OK\|NG\).csv'|sort ...

  2. 数据溢出-varchar类型

    数据溢出一.varchar(65535)1.在charset=latin1,因为有额外的开销,实际只能存65532 CREATE table demo( a ) )charset=latin1 eng ...

  3. ping局域网主机得到外网IP或另一网段IP

    症状::两个笔记本连接到同一个路由器上, 一个ip是 192.168.1.100,主机名是Lenovo-A, 另一个是192.168.1.109,主机名是Lenovo-B 在Lenovo-A 上pin ...

  4. KVM操作命令

    1.查看KVM虚拟机配置文件 Kvm虚机创建 例子 /home/work/kvm-host一下操作目录 qemu-img create -f qcow2 test-Ws.qcow2 10G Test- ...

  5. python-批量解压zip、rar文件

    这是一个用python写解压大量zip脚本的说明,本人新手一个,希望能对各位有所启发. GitHub:https://github.com/lgf133214/Windows-python3- 首先要 ...

  6. 天堂Lineage(單機版)從零開始架設教學 Installing Lineage 3.52 Server - On Windows

      1. [下載原始碼] Using RapidSVN 用checkout      http://l1j-tw-99nets.googlecode.com/svn/trunk/L1J-TW_3.50 ...

  7. [fw]Linux系统使用time计算命令执行的时间

    Linux系统使用time计算命令执行的时间 当测试一个程序或比较不同算法时,执行时间是非常重要的,一个好的算法应该是用时最短的.所有类UNIX系统都包含time命令,使用这个命令可以统计时间消耗.例 ...

  8. React Native实践总结一

    一.React的世界观1.通过改变state来改变视图视图不用考虑如何改变自己,把state画出来即可.2.变量不可变通过创建一个新的state来更改state,使得变更可追踪,不容易因为其他部分修改 ...

  9. shell判断用户是否已经在系统中登录

  10. smbumount - 为普通用户卸载smb文件系统

    总览 smbumount 装载点 描述 普通用户使用这个程序可以卸载smb文件系统.它在工作时会suid到root身份,并且向普通linux用户提供了对资源更多的控制能力.在suid方面,它拥有足够的 ...