Codeforces 490E. Restoring Increasing Sequence 二分

统计有几个‘?‘,然后二分检测取满足条件的最小的数就可以了. 注意没有问号的时候也要检测一下....

E. Restoring Increasing Sequence

time limit per test

1 second

memory limit per test

256 megabytes

input

standard input

output

standard output

Peter wrote on the board a strictly increasing sequence of positive integers a1,?a2,?...,?an.
Then Vasil replaced some digits in the numbers of this sequence by question marks. Thus, each question mark corresponds to exactly one lost digit.

Restore the the original sequence knowing digits remaining on the board.

Input

The first line of the input contains integer n (1?≤?n?≤?105)
— the length of the sequence. Next n lines contain one element of the sequence each. Each element consists only of digits and question marks. No element
starts from digit 0. Each element has length from 1 to 8 characters, inclusive.

Output

If the answer exists, print in the first line "YES" (without the quotes). Next n lines
must contain the sequence of positive integers — a possible variant of Peter‘s sequence. The found sequence must be strictly increasing, it must be transformed from the given one by replacing each question mark by a single digit. All numbers on the resulting
sequence must be written without leading zeroes. If there are multiple solutions, print any of them.

If there is no answer, print a single line "NO" (without the quotes).

Sample test(s)

input

3
?
18
1?

output

YES
1
18
19

input

2
??
?

output

NO

input

5
12224
12??5
12226
?0000
?00000

output

YES
12224
12225
12226
20000
100000
/* ***********************************************
Author        :CKboss
Created Time  :2015年03月14日 星期六 00时09分50秒
File Name     :CF490E_2.cpp
************************************************ */

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <string>
#include <cmath>
#include <cstdlib>
#include <vector>
#include <queue>
#include <set>
#include <map>

using namespace std;

char str[11];
int nine[10]={0,9,99,999,9999,99999,999999,9999999,99999999,999999999};
int len,ni;
vector<int> vi;
bool flag=true;
int fenjie[11],fn;

int getNUMBER(int mid)
{
	int tmid=mid;
	fn=0;
	if(mid==0) fenjie[fn++]=0;
	while(mid)
	{
		fenjie[fn++]=mid%10;
		mid/=10;
	}
	for(int i=fn;i<ni;i++) fenjie[fn++]=0;
	reverse(fenjie,fenjie+fn);
	int ret=0,nx=0;
	for(int i=0;i<len;i++)
	{
		int cs=0;
		if(str[i]!='?') cs=str[i]-'0';
		else if(nx<fn) cs=fenjie[nx++];
		ret=ret*10+cs;
	}
	return ret;
}

int main()
{
    //freopen("in.txt","r",stdin);
    //freopen("out.txt","w",stdout);

	int T_T;
	vi.push_back(0);
	scanf("%d",&T_T);
	while(T_T--)
	{
		scanf("%s",str);
		len=strlen(str);

		if(flag==false) continue;
		/// find ?
		ni=0;
		for(int i=0;i<len;i++) if(str[i]=='?') ni++;
		bool FUCK = false;
		if(str[0]=='?') FUCK=true;
		if(ni==0)
		{
			int nb=0;
			for(int i=0;i<len;i++)
				nb=nb*10+(str[i]-'0');
			if(nb>*(--vi.end())) vi.push_back(nb);
			else flag=false;
		}
		else
		{
			int low=0,high=nine[ni],ans=-1;
			int lastnumber=*(--vi.end());
			if(FUCK) low=(int)(pow(10,ni-1));
			while(low<=high)
			{
				int mid=(low+high)/2;
				int num=getNUMBER(mid);
				if(num>lastnumber) { ans=num; high=mid-1; }
				else low=mid+1;
			}
			if(ans==-1) flag=false;
			else vi.push_back(ans);
		}
	}
	if(flag)
	{
		puts("YES");
		for(int i=1,sz=vi.size();i<sz;i++) printf("%d\n",vi[i]);
	}
	else puts("NO");

    return 0;
}
时间: 2024-10-08 19:49:08

Codeforces 490E. Restoring Increasing Sequence 二分的相关文章

CodeForces 490E Restoring Increasing Sequence(贪心)

CodeForces 490E 题目大意:给N个正整数,然而这些正整数中间有些数字是被'?'遮挡住了,每个'?'可以还原回一个数字,希望给定的这N个整数形成一个递增的序列.可以的话,给出这N个整数的序列,不行返回N0. 解题思路:每个整数都在满足条件的情况下尽量的小,写了一个非递归版本的,发现要考虑的因素太多了,wa了太多遍.后面改成了递归版本的,但是这个比较耗时. 代码: #include <cstdio> #include <cstring> const int MAXL =

CodeForces 490E Restoring Increasing Sequence

题意: 一个严格递增序列  某些数字的某些位被盖住了  求  恢复后的序列 思路: 贪心  让每个数在大于前一个的基础上尽量的小 先讨论数字长度 len[i]<len[i-1] 一定是NO len[i]>len[i-1] 除了第一位如果是?就填1以外  其他?全填0 len[i]==len[i-1] dfs搜索num[i]格式下大于num[i-1]的最小的数 代码: #include<cstdio> #include<iostream> #include<cstr

Codeforces 374D Inna and Sequence 二分+树状数组

题目链接:点击打开链接 给定n个操作,m长的序列a 下面n个数 if(co>=0)则向字符串添加一个co (开始是空字符串) else 删除字符串中有a的下标的字符 直接在序列上搞,简单模拟 #include<stdio.h> #include<iostream> #include<string.h> #include<set> #include<vector> #include<map> #include<math.h&

Increasing Sequence CodeForces - 11A

Increasing Sequence CodeForces - 11A 很简单的贪心.由于不能减少元素,只能增加,过程只能是从左到右一个个看过去,看到一个小于等于左边的数的数就把它加到比左边大,并记录加的次数. 错误记录: 但是很容易错...以前错了4次..过几个月来再做还是不能1A... 比如下面这个有很明显错误的程序 1 #include<cstdio> 2 int n,d,last,now,ans; 3 int main() 4 { 5 int i; 6 scanf("%d%

CodeForces 250B Restoring IPv6 解题报告

Description An IPv6-address is a 128-bit number. For convenience, this number is recorded in blocks of 16 bits in hexadecimal record, the blocks are separated by colons — 8 blocks in total, each block has four hexadecimal digits. Here is an example o

codeforces 250B Restoring IPv6

题目:大意是在说给定一个ipv6地址的简记形式,让你给它补全输出. 简记的规则大致是把地址中的一部分0去掉,其中还包括一连串的0,此时可用::来代替. 方法:首先记录给定的字符串中的:的个数,让后就能确定::中间要补全的0000的个数,然后对于每个小地址(例如bfd),补全失去的0就好了,这时候可以使用printf输出补0的功能,即:printf("%04s",s); 注意:本来每个字符串中:的个数是不能超过7个的,但是会出现::连用,就可能出现8个,这样对于计算::之间补全0000的

codeforces 509D Restoring Numbers

codeforces 509D Restoring Numbers 题意: v[i][j]=(a[i]+b[j])%k 现在给出n*m矩阵v[][], 求a[],b[]和k, 任意一种情况都行. 限制: 1 <= n,m <= 100; 0 <= v[i][j] <= 100 思路: 对于数组a[], 无论怎么变, 数组之间的差始终不变, b[]也同理 利用这个求出k 再设a[0]=0,b[0]=0,求出剩下的东西.

Codeforces 8D Two Friends 三分+二分+计算几何

题目链接:点击打开链接 题意:点击打开链接 三分house到shop的距离,二分这条斜边到cinema的距离 #include<stdio.h> #include<string.h> #include<iostream> #include<algorithm> #include<math.h> #include<set> #include<queue> #include<vector> #include<

Codeforces 486E LIS of Sequence(线段树+LIS)

题目链接:Codeforces 486E LIS of Sequence 题目大意:给定一个数组,现在要确定每个位置上的数属于哪一种类型. 解题思路:先求出每个位置选的情况下的最长LIS,因为开始的想法,所以求LIS直接用线段树写了,没有改,可以用 log(n)的算法直接求也是可以的.然后在从后向前做一次类似LIS,每次判断A[i]是否小于f[dp[i]+1],这样就可以确定该位 置是否属于LIS序列.然后为第三类的则说明dp[i] = k的只有一个满足. #include <cstdio>