华农acm:scau 9508 诸葛给我牌

7 篇文章 0 订阅
3 篇文章 0 订阅
题目
9508 诸葛给我牌
时间限制:1000MS  内存限制:65535K
提交次数:0 通过次数:0

题型: 编程题   语言: G++;GCC
Description
    


    三国杀是现在流行的桌游..分为两方,用牌来进行对战,每一张牌都有自己的属性,而每一个武将(就是玩家)都有自己的技能.
    每一次玩家都从牌堆里面抽两张牌到手牌上,然后进行出牌杀死对方玩家(更具体请参考官方说明)..
    诸葛亮的技能就是能看到牌堆上面的5张牌而可以对这5张牌进行摆放,绝对自己或者下家得到的牌.
    而甄姬的技能就是一开始可以在牌堆里面摸牌,只要摸到的是黑色牌都可以拿到手牌上,一直摸到不是黑色的牌为止.
    现在诸葛亮和甄姬刚好坐在一起,甄姬成为了诸葛亮的下家.现在诸葛亮想让甄姬拿到尽可能多的牌.应该如何摆放牌呢
    现在将诸葛亮的技能加强点(5张太少了,不够给力),他可以看到牌堆的所有牌,但他不能抽牌,而只能去掉牌堆里面的某些牌,而去掉牌要符合以下规则
    1.	从牌顶一直拿
    2.	从牌中间拿出连续的一段牌
    这两个规则最多只能用一次或者不用
    而且这技能是在诸葛亮拿完自己的手牌才发动的,问甄姬最多能拿到多少张呢
    由于牌要不是红,要不是黑,则0表示黑,1表示红
    例如
    00011101100111000000
    如果我把前面的111拿走,那么甄姬就能拿到前面的4个0
    如果我把000111和之后的11拿走,则变为0(11)00111000000,则甄姬可以拿到前面的3张,括号表示已经拿走
    但如果我把前面的000111011和最后的111拿走,就甄姬就可以拿到000000000.  8张了
    那如果把中间的11101100111拿走呢? 我们可以拿到9张。
    记住牌顶和中间都只能拿一次或者不拿



输入格式
    第一行表示串长n(1<=n<=1000000)
    第二行是长度为n的01串表示牌堆里面的牌


输出格式
    一个数表示最多可以拿到的牌数


输入样例
20
00011101100111000000


输出样例
9


来源 ick2 

作者 a470086609

题解:

  简单来说就是找两个最长的0长度。

详细:有两种方式,第一种是去掉头部的1这样使得一开始能够读到0,而不是1导致中断。然后找到一个最长的0

但是这样会导致一个错误:11101000100000

如果只是去掉111那么,然后去掉1这样会导致并不是最长

那么我们想要的其实是(11101}000(1)00000

如果存在两个最长的那么我们自然后办法将他们两个链接在一起。


Code:

#ifdef local
#include    <ctime>
#endif
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <string>
#include <cmath>
#include <cstdlib>
#include <vector>
#include <queue>
#include <set>
#include <map>
#define rep(i,e) for(int i=0;i<e;i++)
#define rep1(i,e) for(int i=1;i<=e;i++)
#define repx(i,x,e) for(int i=x;i<=e;i++)
#define ll long long
#define pii pair<int,int>
#define F first
#define S second
#define pb push_back
#define mp make_pair
#define mset(var,val) memset(var,val,sizeof(var))
#define IOS ios::sync_with_stdio(false);cin.tie(0)
#define scd(a) scanf("%d",&a)
#define scdd(a,b) scanf("%d%d",&a,&b)
#define scddd(a,b,c) scanf("%d%d%d",&a,&b,&c)
#define test(a) cout<<a<<endl
#define test2(a,b) cout<<a<<" "<<b<<endl
#define test3(a,b,c) cout<<a<<" "<<b<<" "<<c<<endl
typedef unsigned long long ull;
using namespace std;
const int inf = 0x3f3f3f3f;
const int N = 1e6 + 10;
struct node
{
	int s,e;
	int flag;
}P[5];
char line[N];
int  len[N];
void work() {
	int n;
	cin >> n;
	cin >> line;
	int pos=0;
	line[n]='1';
	int cnt=0;
	int temp=0;
	for(int i=pos;i<=n;i++){
		if(line[i]=='0'){
			temp++;
		}else{		
			len[cnt]=temp;
			cnt++;
			temp=0;
		}
	}
	sort(len,len+cnt);
	int cur=cnt;
	if(cur>=2){
		cout<<len[cur-1]+len[cur-2]<<endl;
	}else{
		cout<<len[0]<<endl;
	}
}
int main() {
#ifdef local
	freopen("in.txt", "r", stdin);
	freopen("out", "w", stdout);
	clock_t t_begin = clock();
#endif
	IOS;
	work();
#ifdef local
	clock_t t_end = clock();
	double time = (t_end - t_begin) / (double)(CLOCKS_PER_SEC);
	printf("\n\n\nTime_used=%.10lf", time);
#endif
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值