测评会员优惠活动进行中 · 开通 VIP,有效期内测评不限次 VIP 优惠中 · 测评不限次 立即查看

A29781. 拼大数

填空题 中等

题目描述

拼大数

题目描述

如何随机生成一个有n个数的大数呢?一种方法是,找到n个小朋友,每人发一张卡片,卡片一面写着编号(这里假设小朋友们从1到n编号),另一面让他们随便写下一个1位数字。然后让小朋友们把自己的卡片在墙上钉成一排,要求一张挨着一张,按他们的编号升序排列,显示他们自己写的的数字。

但是,让十万个小孩都按指令行动,可太难了。结果是卡片乱七八糟满墙都是,有些甚至显示的不是正确的面。例如,第 23 号小朋友在卡片上写8,我们在墙上应该看到8,但是却看到了23......你的任务就是把这些卡片整理好,得到我们真想要拼成的大数。

输入

输入第一行给出一个正整数 n (≤105)

然后n行,每行按 n1  n2 的格式给出一张卡片两面的数字。

输出

在一行中输出我们真想要拼成的n位大数。如果卡片两面都是1位数,那么就很难说哪个数字是小朋友自己写的,所以解可能是不唯一的。这时候需要输出能得到的最小的数字。

(保证是n位数)

输入样例

12
7 11
8 9
3 1
2 12
4 6
10 0
5 1
2 5
6 8
1 4
7 2
9 3

输出样例

359114268072

参考答案

#include<iostream> using namespace std; /* 思路: 根据小朋友编号来考虑 只有编号小于10的9个小朋友才需要考虑他们真正的编号 大于等于10的那些小朋友根据卡牌两边数字能知道(写的数字只能是1位) 使用深搜找出“个位编号”小朋友的位置, 找出所有可能,取最小 */ struct node { int n1; int n2; int flag; //用于深搜是否被遍历过 }; int n,cnt=0; //cnt:不确定的数字(1位数)个数 node t[15]; int num[100005]= {0}; int search_ans[15]= {-1}; //搜索的答案临时保存位置,0号位置-1为是否第一次找到 void dfs(int x) { //当前找编号x if(x>=10 || x>cnt) { //1~9都找到了 找完了 //先判断是否比之前答案小 if(search_ans[0]==-1) { //第一次找到 search_ans[0]=1; //标记不是第一次找到 for(int i=1; i<=cnt; i++) num[i]=search_ans[i]; } else { //非第一次,判断是否更小 for(int i=1; i<=cnt; i++) { if(search_ans[i]>num[i]) return; //不是更小的 if(search_ans[i]<num[i]) { //更小 for(int j=1; j<=cnt; j++) num[j]=search_ans[j]; return; } } } return; } for(int i=0; i<cnt; i++) { //遍历t数组,找编号x if(t[i].flag==0) { //还没被遍历过 if(t[i].n1==x || t[i].n2==x) { //n1或n2是编号i t[i].flag=1; //标记访问 //1是编号哪2就是数字,反之一样 search_ans[x]= (t[i].n1==x) ? t[i].n2:t[i].n1; dfs(x+1); //搜索下一个 t[i].flag=0; //回溯 } } } } int main() { cin>>n; //输入n个小朋友 for(int i=0; i<n; i++) { int n1,n2; cin>>n1>>n2; if(n1>n2) swap(n1,n2); //小的可能是编号,放前面 if(n2>=10) num[n2]=n1; //n2肯定是编号,n1是1位数 else { //两个都是1位数 ,放入t数组 t[cnt].n1=n1; t[cnt].n2=n2; t[cnt].flag=0; //用于深搜是否被遍历过 cnt++; } } dfs(1); //深搜 for(int i=1; i<=n; i++) //输出答案 cout<<num[i]; return 0; }
上一题 下一题