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

  1. CF #376 (Div. 2) C. dfs

    1.CF #376 (Div. 2)    C. Socks       dfs 2.题意:给袜子上色,使n天左右脚袜子都同样颜色. 3.总结:一开始用链表存图,一直TLE test 6 (1)如果需 ...

  2. CF #375 (Div. 2) D. bfs

    1.CF #375 (Div. 2)  D. Lakes in Berland 2.总结:麻烦的bfs,但其实很水.. 3.题意:n*m的陆地与水泽,水泽在边界表示连通海洋.最后要剩k个湖,总要填掉多 ...

  3. CF #374 (Div. 2) D. 贪心,优先队列或set

    1.CF #374 (Div. 2)   D. Maxim and Array 2.总结:按绝对值最小贪心下去即可 3.题意:对n个数进行+x或-x的k次操作,要使操作之后的n个数乘积最小. (1)优 ...

  4. CF #374 (Div. 2) C. Journey dp

    1.CF #374 (Div. 2)    C.  Journey 2.总结:好题,这一道题,WA,MLE,TLE,RE,各种姿势都来了一遍.. 3.题意:有向无环图,找出第1个点到第n个点的一条路径 ...

  5. CF #371 (Div. 2) C、map标记

    1.CF #371 (Div. 2)   C. Sonya and Queries  map应用,也可用trie 2.总结:一开始直接用数组遍历,果断T了一发 题意:t个数,奇变1,偶变0,然后与问的 ...

  6. 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) ,问在每个区间里所有 ...

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

  8. 【CF】222 Div.1 B Preparing for the Contest

    这样类似的题目不少,很多都是一堆优化条件求最优解,这个题的策略就是二分+贪心.对时间二分, 对费用采用贪心. /* 377B */ #include <iostream> #include ...

  9. CF#138 div 1 A. Bracket Sequence

    [#138 div 1 A. Bracket Sequence] [原题] A. Bracket Sequence time limit per test 2 seconds memory limit ...

随机推荐

  1. 第一篇:初始Golang

    Golang简介 编程语言已经非常多,偏性能敏感的编译型语言有 C.C++.Java.C#.Delphi和Objective-C 等,偏快速业务开发的动态解析型语言有PHP.Python.Perl.R ...

  2. Linux内核入门(六)—— __attribute__ 机制【转】

    转自:https://blog.csdn.net/yunsongice/article/details/5538020 GNU C的一大特色(却不被初学者所知)就是__attribute__机制.__ ...

  3. centos7下安装配置redis3.0.4

    安装redis 1.进入redis官网(redis.io)下载redis稳定版安装包,目前稳定版本为3.0.4 2.在linux  /usr文件夹下新建redis文件夹,拷贝安装包redis-3.0. ...

  4. MongoDB存储基础教程

    一.MongoDB简介 1. mangodb是一种基于分布式.文件存储的非关系型数据库 2. C++写的,性能高 3. 为web应用提供可扩展的高性能数据存储解决方案 4. 所支持的格式是json格式 ...

  5. Kali Linux上安装SSH服务

    安装 SSH 从终端使用 apt-get 命令安装 SSH 包: # apt-get update # apt-get install ssh 启用和开始使用 SSH 为了确保安全 shell 能够使 ...

  6. 10 Go 1.10 Release Notes

    Go 1.10 Release Notes Introduction to Go 1.10 Changes to the language Ports Tools Default GOROOT &am ...

  7. sublime text2快捷键

    mac: command+option+f : 替换, find what: (.*) replace with:"$1": "1"     或者: data: ...

  8. Caffe学习系列(17): blob

    对于blob.h文件. 先看成员变量.定义了6个保护的成员变量,包括前.后向传播的数据,新.旧形状数据(?), 数据个数及容量. 再看成员函数.包括构造函数(4个参数),reshape(改变blob形 ...

  9. Android仿苹果版QQ下拉刷新实现(二) ——贝塞尔曲线开发"鼻涕"下拉粘连效果

    前言 接着上一期Android仿苹果版QQ下拉刷新实现(一) ——打造简单平滑的通用下拉刷新控件 的博客开始,同样,在开始前我们先来看一下目标效果: 下面上一下本章需要实现的效果图: 大家看到这个效果 ...

  10. Qt QByteArray或者Char转十六进制 QString

    1.QByteArray转十六进制 QByteArray buff = sp->readAll(); qDebug() << buff.toHex() << " ...