1. 程式人生 > >2017北京國慶刷題Day1 morning T2

2017北京國慶刷題Day1 morning T2

strong tdi get 好用 ns2 刷題 ios 輸出格式 ++

T2火柴棒 (stick)

Time Limit:1000ms Memory Limit:128MB

題目描述

眾所周知的是,火柴棒可以拼成各種各樣的數字。具體可以看下圖:

通過2根火柴棒可以拼出數字“1”,通過5根火柴棒可以拼出數字“2”,以此類推。

現在LYK擁有k根火柴棒,它想將這k根火柴棒恰好用完,並且想知道能拼出的最小和最大的數分別是多少。

輸入格式(stick.in)

一個數k。

輸出格式(stick.out)

兩個數,表示最小的數和最大的數。註意這兩個數字不能有前導0。

輸入樣例

15

輸出樣例

108 7111111

數據範圍

對於30%的數據k<=10。

對於60%的數據k<=20。

對於100%的數據1<k<=100。

k<=1e5可做?

知道什麽叫搜索嗎?就是dfs啊~

可以過k<=100000

貪心有反例 比如31 最小數是20088 不是22888

加了那麽十來句剪枝就很快了~ 理論上還能更快

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>

#define N 10100000

using
namespace std; int n,m,k,len1,len2,num,opt; int ans1[N],ans2[N],pre[N],tmp[N],len; int use[10]={6,2,5,5,4,5,6,3,7,6}; bool cmp(int a,int b){return a>b;} inline int read() { int x=0,f=1;char c=getchar(); while(c>9||c<0){if(c==-)f=-1;c=getchar();} while(c>=0&&c<=
9){x=x*10+c-0;c=getchar();} return x*f; } void update(int num) { if(len1<num) return;//8 if(len1==num && pre[1]>ans1[1] || pre[2]>ans1[2]) return;//9 for(int i=1;i<=num;i++) tmp[i]=pre[i]; sort(pre+1,pre+num+1); if(pre[1]==0) for(int i=1;i<=num;i++) { if(pre[i]!=0){int j=pre[i];pre[i]=0;pre[1]=j;break;} } int flag=0;if(len1>num) flag=1; else for(int i=1;i<=num;i++) { if(pre[i]<ans1[i]) { flag=1;break; } } if(len1<num) flag=0; if(flag) { for(int i=1;i<=num;i++) ans1[i]=pre[i];len1=num; } for(int i=1;i<=num;i++) pre[i]=tmp[i]; } void dfs(int res) { if(res==0) { update(num); return; } //if(opt) return; /*if(res%7==0) { for(int i=1;i<=num;i++) ans1[i]=pre[i]; for(int i=num+1;i<=num+res/7;i++) ans1[i]=8; opt=1; }*/ if(pre[1]>ans1[1] || pre[2]>ans1[2]) return;//1 if(len1-num>0 && (len1-num)*7-res<0) return;//2 if(num>len1/2 && k-res<res) return;//3 if(num>=len1) return;//4 if(res<2) return;//5 for(int i=0;i<=9;i++) { if(res==2 && i>1) break;//6 if(res==4 && i>4) break;//7 if(i==0 && num==0) continue; if(res-use[i]<0) continue; num+=1; pre[num]=i; dfs(res-use[i]);num--; } } int main() { k=read(); memset(ans1,127/3,sizeof ans1); len1=k/7+1; if(k%2==0) for(int i=1;i<=k/2;i++) ans2[i]=1; if(k%2!=0) {for(int i=2;i<=k/2;i++) ans2[i]=1;ans2[1]=7;} if(k%7==0) for(int i=1;i<=k/7;i++) ans1[i]=8,len1=k/7; else dfs(k); for(int i=1;i<=len1;i++) printf("%d",ans1[i]); printf(" "); for(int i=1;i<=k/2;i++) printf("%d",ans2[i]); return 0; }

2017北京國慶刷題Day1 morning T2