637(Div.2)D.Nastya and Scoreboard

题目描述

Denis, who managed to buy flowers and sweets (you will learn about this story in the next task), went to a meeting with Nastya to invite her to become a couple. And so, they sit together in a cafe, chatting. Denis finally offers to be them together, but … Nastya doesn’t give any answer.
The poor boy was very upset due to that. He was so sad that he kicked some kind of scoreboard with numbers. The numbers are displayed in the same way as on an electronic clock: each digit position consists of 7 segments, which can be turned on or off to display different numbers. The picture shows how all 10 decimal digits are displayed:
637(Div.2)D.Nastya and Scoreboard_第1张图片
After the kick, some sticks stopped working, that is, some sticks might stop glowing if they glowed earlier. But Denis remembered how many sticks were glowing and how many are glowing now. Let exactly k sticks break and we know which sticks are working now. Denis came up with the question: what is the maximum number that can burn on the board if you turn on exactly k sticks (which are off now)?
It is allowed that the number includes leading zeros.

Input

The first line contains integer n (1≤n≤2000) — the number of digits on scoreboard and k (0≤k≤2000) — the number of sticks that stopped working.
The next n lines contain one binary string of length 7, the i-th of which encodes the i-th digit of the scoreboard.
Each digit on the scoreboard consists of 7 sticks. We number them, as in the picture below, and let the i-th place of the binary string be 0 if the i-th stick is not glowing and 1 if it is glowing. Then a binary string of length 7 will specify which sticks glowing.637(Div.2)D.Nastya and Scoreboard_第2张图片
Thus, the sequences “1110111”, “0010010”, “1011101”, “1011011”, “0111010”, “1101011”, “1101111”, “1010010”, “1111111”, “1111011” encode in sequence all digits from 0 to 9 inclusive.

Output

Print a single number consisting of n digits — the maximum number that can be obtained if you turn on exactly k sticks or −1, if it is impossible to turn on exactly k sticks so that some sort of sequence appears on the scoreboard digits.

Examples

input
1 7
0000000
output
8
input
2 5
0010010
0010010
output
97
input
3 5
0100001
1001001
1010011
output
-1

Note

In the first test, we are obliged to include all 7 sticks and get one 8 digit on the scoreboard.
In the second test, we have sticks turned on so that units are formed. For 5 of additionally included sticks, you can get the numbers 07, 18, 34, 43, 70, 79, 81 and 97, of which we choose the maximum — 97.
In the third test, it is impossible to turn on exactly 5 sticks so that a sequence of numbers appears on the scoreboard.

题目大意

有一块电子显示屏,0~9的显示如图。给n块显示屏,和它们现在的状态( 不一定是某个数字 ),问能否再打开正好k个灯管,让n块显示屏显示出一个数,要求这个数尽可能大。输入为长度为7的01字符串,1表示亮着,0表示没亮。

题目分析

这道题可以用dfs来爆搜。从大到小(因为要求最大值)枚举每一个数的每一位。看看是否符合条件,符合条件输出即可。
要注意的是直接爆搜会超时,因此我们需要用一个数组来存储每一种情况,从而避免重复计算

ac代码
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#define LL long long
using namespace std;
const int N=2005;
string s[10]={"1110111","0010010","1011101","1011011",
"0111010","1101011","1101111","1010010","1111111","1111011"};
int n;          //用数组s来存0-9
string a[N];    //用a存给出的数
bool flag=0,st[N][N];  //flag判断是否已经有解,用st[]存不合法的情况,避免重复计算
int ans[N];     //用ans来存答案
void dfs(int pos,int k)    //pos表示枚举到了第几个数,k是剩余修改次数
{
	if(flag||k<0) return;  //如果有解或修改次数为负则结束
	if(pos==n)
	{   //如果枚举完n个数且剩余修改次数正好为0,则输出答案并记录
		if(k==0)
		{
			flag=true;
			for(int i=0;i<n;i++) cout<<ans[i];
			cout<<endl;
			return;
		}
		else return;
	}
    if(st[pos][k]) return;  //已经算出了该状态不合法,返回
	for(int i=9;i>=0;i--)   //因为要求最大值,所以从大到小枚举
	{
		int cnt=0;       //记录a[pos]修改成数i需要的次数
		bool state=false;//记录a[pos]能否修改成数i
		for(int j=0;j<7;j++)  //枚举每一位
		if(a[pos][j]=='0'&&s[i][j]=='1') cnt++; //修改需要打开该灯管则可以修改
		else if(a[pos][j]=='1'&&s[i][j]=='0') 
		{   //修改需要关闭该灯管,则不可修改,所以,a[pos]不能改为数i
			state=true;
			break;
		}
		
		if(state) continue;
		ans[pos]=i;        //可以修改则用ans记录
		dfs(pos+1,k-cnt);  //继续枚举下一个数
	}
	if(!flag) st[pos][k]=true;  //如果枚举完毕还没有得到解,说明该情况不
}                               //合法,用st数组记录
int main()
{
    int k;
    cin>>n>>k;
    for(int i=0;i<n;i++)
    cin>>a[i];
    
    dfs(0,k);
    
    if(!flag) puts("-1");   //如果没有解输出-1
    return 0;
}

你可能感兴趣的:(Codeforces)