CF 222 (DIV 1)
A:
我是bfs出一颗树,然后删掉树后面的k个结点。
其实也可以直接bfs出一块连通的s - k个点,其余的.打X就可以了。
很水的题目。
/* ***********************************************
Author :kuangbin
Created Time :2013-12-29 23:26:26
File Name :E:\2013ACM\CF比赛\CF222\A.cpp
************************************************ */ #include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <string>
#include <math.h>
#include <stdlib.h>
#include <time.h>
using namespace std;
char str[][];
bool vis[][];
int n,m,k;
pair<int,int> p[*];
int cnt;
int Move[][] = {{,},{,-},{,},{-,}};
queue<pair<int,int> >q;
void bfs(int x0,int y0)
{
memset(vis,false,sizeof(vis));
cnt = ;
while(!q.empty())q.pop();
q.push(make_pair(x0,y0));
vis[x0][y0] = true;
p[cnt++] = make_pair(x0,y0);
while(!q.empty())
{
pair<int,int> tmp = q.front();
q.pop();
for(int i = ;i < ;i++)
{
int x = tmp.first + Move[i][];
int y = tmp.second + Move[i][];
if(x < || y < || x >= n || y >= m)continue;
if(vis[x][y])continue;
if(str[x][y] == '#')continue;
p[cnt++] = make_pair(x,y);
vis[x][y] = true;
q.push(make_pair(x,y));
}
}
} int main()
{
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
while(cin>>n>>m>>k)
{
for(int i = ;i < n;i++)
scanf("%s",str[i]);
int x0 , y0 = -;
for(int i = ;i < n;i++ )
{
if(y0 != -)break;
for(int j = ;j < m;j++)
if(str[i][j] == '.')
{
x0 = i;y0 = j;
break;
}
}
bfs(x0,y0);
for(int i = ;i < k;i++)
{
int x = p[cnt--i].first;
int y = p[cnt--i].second;
str[x][y] = 'X';
}
for(int i = ;i < n;i++)
cout<<str[i]<<endl;
}
return ;
}
B:
题目很长,自己看吧!
使用二分+判断就可以了。复杂度大概是n * log(10^9)*log(n).
二分天数,在1~m 的范围二分。
天数为mid天时候,判断。按照a的大小,从大到小,在满足b>=a的里面,找出一个c最小的,然后连续删掉mid个a.
最后判断总价。
使用优先队列写的,用set也可以。
/* ***********************************************
Author :kuangbin
Created Time :2013-12-29 23:57:57
File Name :E:\2013ACM\CF比赛\CF222\B.cpp
************************************************ */ #include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <string>
#include <math.h>
#include <stdlib.h>
#include <time.h>
using namespace std;
const int MAXN = ;
int a[MAXN];
int b[MAXN];
int c[MAXN];
int n,m,s; struct node
{
int x, y;
int index;
friend bool operator < (node a, node b)
{
return a.y > b.y; //结构体中,y小的优先级高
}
};
priority_queue<node>q; //适用于正负整数
template <class T>
inline bool scan_d(T &ret) {
char c; int sgn;
if(c=getchar(),c==EOF) return ; //EOF
while(c!='-'&&(c<''||c>'')) c=getchar();
sgn=(c=='-')?-:;
ret=(c=='-')?:(c-'');
while(c=getchar(),c>=''&&c<='') ret=ret*+(c-'');
ret*=sgn;
return ;
} node nn[MAXN];
bool cmp(node a,node b)
{
return a.x > b.x;
}
int AA[MAXN];
bool cmp11(int t1,int t2)
{
return a[t1] > a[t2];
}
int BB[MAXN]; bool check(int pp)
{
while(!q.empty())q.pop();
int i = ,j = ;
long long ret = ;
while(i < m)
{
while(j < n && nn[j].x >= a[i])
{
q.push(nn[j]);
j++;
}
if(q.empty())return false;
node tmp = q.top();
q.pop();
ret += tmp.y;
if(ret > s)return false;
int ccc = pp;
while(ccc && i < m)
{
ccc--;
BB[AA[i]] = tmp.index;
i++;
}
}
return true;
} int main()
{
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
while(scanf("%d%d%d",&n,&m,&s) == )
{
for(int i = ;i < m;i++)
{
scan_d(a[i]);
}
for(int i = ;i < n;i++)
scan_d(b[i]);
for(int i = ;i < n;i++)
scan_d(c[i]);
for(int i = ;i < m;i++)
AA[i] = i;
sort(AA,AA+m,cmp11);
sort(a,a+m);
reverse(a,a+m);
for(int i = ;i < n;i++)
{
nn[i].x = b[i];
nn[i].y = c[i];
nn[i].index = i+;
}
sort(nn,nn+n,cmp);
if(check(m) == false)
{
printf("NO\n");
continue;
}
int l = , r = m;
int ans;
while(l <= r)
{
int mid = (l + r)/;
if(check(mid))
{
ans = mid;
r = mid -;
}
else l = mid+;
}
check(ans);
printf("YES\n");
for(int i = ;i < m;i++)
{
printf("%d",BB[i]);
if(i < m-)printf(" ");
else printf("\n");
}
}
return ;
}
C:
比较有意思的题目。
其实s数组从大到小排序以后,只和前m大的数有关的,后面的无关。
m<=20
一种是复杂度为 m * m * 2^m 的算法,虽然复杂度比较大,可以勉强在CF上跑过去。
使用dp[20][1<<20], dp[i][j] 表示前m个s数组存在情况为j时候,处理到第i步。
答案就是dp[0][(1<<m)-1]
然后就是枚举当前步是取哪一个,或者去掉哪一个,或者忽略这个操作。
代码如下(不建议看,复杂度大)
/* ***********************************************
Author :kuangbin
Created Time :2013-12-30 1:06:58
File Name :E:\2013ACM\CF比赛\CF222\C.cpp
************************************************ */ #include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <string>
#include <math.h>
#include <stdlib.h>
#include <time.h>
using namespace std;
const int INF = 0x3f3f3f3f; int s[];
int n,m;
struct Node
{
char op[];
int id;
};
Node node[];
bool used[];
int a[];
int cnt;
int dp[][<<];
int loc[<<]; int bit[];
int main()
{
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
for(int i = ;i <= ;i++)
loc[<<i] = i;
for(int i = ;i < ;i++)
bit[i] = <<i;
while(cin>>n)
{
for(int i = ;i < n;i++)
cin>>s[i];
sort(s,s+n);
reverse(s,s+n);
cnt = ;
scanf("%d",&m);
for(int i = ;i < m;i++)
{
scanf("%s%d",node[i].op,&node[i].id);
}
int tot = (<<m);
memset(dp,,sizeof(dp));
for(int i = m-;i >= ;i--)
for(int j = ;j < tot;j++)
{
if(j == )
{
continue;
}
if(node[i].id == )dp[i][j] = -INF;
else dp[i][j] = INF;
for(int id = ;id < m;id++)
{
if((j & bit[id]) == )continue; if(node[i].id == )
{
if(node[i].op[] == 'p')
dp[i][j] = max(dp[i][j],max(dp[i+][j],dp[i+][j ^ bit[id]] + s[id]));
else dp[i][j] = max(dp[i][j],max(dp[i+][j],dp[i+][j ^ bit[id]]));
}
else
{ if(node[i].op[] == 'p')
dp[i][j] = min(dp[i][j],min(dp[i+][j],dp[i+][j ^ bit[id]] - s[id]));
else dp[i][j] = min(dp[i][j],min(dp[i+][j],dp[i+][j ^ bit[id]]));
}
}
}
printf("%d\n",dp[][tot-]);
}
return ;
}
其实操作根本不会被忽略,每一步肯定要操作的。
所以状态可以减少一维,直接dp[i], 根据i中多少个0,就知道取了多少个了。
这样复杂度降为 m * 2^m
写起来也很方便
/* ***********************************************
Author :kuangbin
Created Time :2013-12-30 2:22:12
File Name :E:\2013ACM\CF比赛\CF222\CC.cpp
************************************************ */ #include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <string>
#include <math.h>
#include <stdlib.h>
#include <time.h>
using namespace std; const int INF = 0x3f3f3f3f;
int s[];
int n,m;
struct Node
{
char op[];
int id;
}node[];
int dp[<<];
bool vis[<<]; int solve(int st)
{
if(vis[st])return dp[st];
vis[st] = true;
int cnt = ;
for(int i = ;i < m;i++)
if((st & (<<i)) == )
cnt++;
if(st == )return dp[st] = ;
if(node[cnt].id == )
{
dp[st] = -INF;
for(int i = ;i < m;i++)
if(st & (<<i))
{
if(node[cnt].op[] == 'p')
dp[st] = max(dp[st],solve(st ^ (<<i)) + s[i]);
else dp[st] = max(dp[st],solve(st ^ (<<i)));
}
}
else
{
dp[st] = INF;
for(int i = ;i < m;i++)
if(st & (<<i))
{
if(node[cnt].op[] == 'p')
dp[st] = min(dp[st],solve(st ^ (<<i)) - s[i]);
else dp[st] = min(dp[st],solve(st ^ (<<i)));
}
}
return dp[st];
} int main()
{
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
while(cin>>n)
{
for(int i = ;i < n;i++)
cin>>s[i];
sort(s,s+n);
reverse(s,s+n);
cin>>m;
for(int i = ;i < m;i++)
scanf("%s%d",node[i].op,&node[i].id);
memset(vis,false,sizeof(vis));
printf("%d\n",solve((<<m) - ));
}
return ;
}
D :
待补中
E:
待补中
CF 222 (DIV 1)的更多相关文章
- CF #376 (Div. 2) C. dfs
1.CF #376 (Div. 2) C. Socks dfs 2.题意:给袜子上色,使n天左右脚袜子都同样颜色. 3.总结:一开始用链表存图,一直TLE test 6 (1)如果需 ...
- CF #375 (Div. 2) D. bfs
1.CF #375 (Div. 2) D. Lakes in Berland 2.总结:麻烦的bfs,但其实很水.. 3.题意:n*m的陆地与水泽,水泽在边界表示连通海洋.最后要剩k个湖,总要填掉多 ...
- CF #374 (Div. 2) D. 贪心,优先队列或set
1.CF #374 (Div. 2) D. Maxim and Array 2.总结:按绝对值最小贪心下去即可 3.题意:对n个数进行+x或-x的k次操作,要使操作之后的n个数乘积最小. (1)优 ...
- CF #374 (Div. 2) C. Journey dp
1.CF #374 (Div. 2) C. Journey 2.总结:好题,这一道题,WA,MLE,TLE,RE,各种姿势都来了一遍.. 3.题意:有向无环图,找出第1个点到第n个点的一条路径 ...
- CF #371 (Div. 2) C、map标记
1.CF #371 (Div. 2) C. Sonya and Queries map应用,也可用trie 2.总结:一开始直接用数组遍历,果断T了一发 题意:t个数,奇变1,偶变0,然后与问的 ...
- CF #365 (Div. 2) D - Mishka and Interesting sum 离线树状数组
题目链接:CF #365 (Div. 2) D - Mishka and Interesting sum 题意:给出n个数和m个询问,(1 ≤ n, m ≤ 1 000 000) ,问在每个区间里所有 ...
- CF #365 (Div. 2) D - Mishka and Interesting sum 离线树状数组(转)
转载自:http://www.cnblogs.com/icode-girl/p/5744409.html 题目链接:CF #365 (Div. 2) D - Mishka and Interestin ...
- 【CF】222 Div.1 B Preparing for the Contest
这样类似的题目不少,很多都是一堆优化条件求最优解,这个题的策略就是二分+贪心.对时间二分, 对费用采用贪心. /* 377B */ #include <iostream> #include ...
- CF#138 div 1 A. Bracket Sequence
[#138 div 1 A. Bracket Sequence] [原题] A. Bracket Sequence time limit per test 2 seconds memory limit ...
随机推荐
- asp.net将ppt文档转换成pdf
一.添加引用 using Microsoft.Office.Core;using Microsoft.Office.Interop.PowerPoint; 二.转换方法 C# 代码 复制 // ...
- 从字节码的角度看Java内部类与外部类的互相访问
Java中non-static内部类为何可以访问外部类的变量?Java中外部类又为何可以访问内部类的private变量?这两个问题困扰过我一段时间,查了一些网上的答案,大多从“闭包”概念入手,理解起来 ...
- 02 workerman之GatewayWorker简单的demo 实现两端发送消息
前端代码: <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <t ...
- 关联查询resultMap使用规则总结——(十一)
resultType: 作用: 将查询结果按照sql列名pojo属性名一致性映射到pojo中. 场合: 常见一些明细记录的展示,比如用户购买商品明细,将关联查询信息全部展示在页面时,此时可直接使用re ...
- Ansible Tower系列 三(使用tower执行一个任务)【转】
创建playbook Tower playbook 项目默认存在 /var/lib/awx/projects/ su - awx cd projects/ mkdir ansible-for-devo ...
- 【前端vue开发】vue开发输入姓名,电话,公司表单提交组件
<template> <div id="parti-info"> <div> <span>您的姓名:</span> &l ...
- node koa2
http://www.codes51.com/itwd/4316421.html 问题: (node.js)nodejs koa ctx=> 报错描述: 刚开始接触 koa 一直提示 ctx=& ...
- CF1064B 【Equations of Mathematical Magic】
题目要求解$a-(a\oplus x)-x=0$的解$x$的个数 移项得$a-x=a\oplus x$ $a$的二进制形式,应该是一个$01$串,异或的过程是不能影响到两个不同的位的,所以我们按位考虑 ...
- 【转载】redis容灾策略
版权声明:转载请注明出处 http://blog.csdn.net/irean_lau. https://blog.csdn.net/Irean_Lau/article/details/5136027 ...
- ansible学习
声明:本博客内容是根据惨绿少年内容实践随笔,地址:http://www.cnblogs.com/clsn/p/7743792.html#comment_form 1.ansible介绍 Ansible ...