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. 浅说Get请求和Post请求

    Web 上最常用的两种 Http 请求就是 Get 请求和 Post 请求了.我们在做 java web 开发时,也总会在 servlet 中通过 doGet 和 doPost 方法来处理请求:更经常 ...

  2. mysql基本操作【重要】

    aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAuYAAAVeCAIAAACyxWmSAAAgAElEQVR4nOydT0wbV/vvZzm7YXd2zI ...

  3. slf4j MDC使用

    slf4j MDC使用 最近也是在项目代码里发现一个地方有个MDC.put(),忍不住好奇点了进去,于是知道了MDC这个东西,细研究一下,发现还真是个好东西. MDC解决了什么问题 MDC全名Mapp ...

  4. mac 安装gevent报错

    运行pip install gevent报错 错误信息如下 xcrun: error: invalid active developer path (/Library/Developer/Comman ...

  5. 解决windows10 里vs2017 直接开始执行提示“此任务要求应用程序有提升的权限”1.

    1.打开vs的安装路径,我的是 C:\Program Files (x86)\Common Files\Microsoft Shared\MSEnv\ ,找到  VSLauncher.exe 右击该文 ...

  6. InteliJ IDEA 简单使用:配置项目所需jdk

    1:配置项目所需jdk: File->Project Structure 弹出如下界面: 首先选中SDKs,会出现下图界面:点击“+”标志弹出Add New SDK 然后选择JDK,会弹出路径框 ...

  7. jexus - 分析日志文件

    1.统计IP访问次数 awk '{print $3}' default |sort -n|uniq -c|sort -rn|head

  8. 利用CSS改变输入框的光标颜色

    转:http://www.cnblogs.com/gymmer/p/6810367.html 代码: <!DOCTYPE html> <html lang="en" ...

  9. 局域网搭建https局域网

    局域网搭建https局域网 1.使用tomcat作为服务器搭建局域网访问https 需要使用java jdk\bin下的keytool.exe来创建证书 使用命令:keytool -genkenpai ...

  10. http://blog.csdn.net/five3/article/details/7181521

    首先来了解什么是multipart/form-data请求: 根据http/1.1 rfc 2616的协议规定,我们的请求方式只有OPTIONS.GET.HEAD.POST.PUT.DELETE.TR ...