日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

【2018.3.10】模拟赛之一-ssl2574Closest【深搜】

發布時間:2023/12/3 编程问答 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【2018.3.10】模拟赛之一-ssl2574Closest【深搜】 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

目錄地址

前言

感謝黎某兒(劃掉)教我這道題☆⌒(*^-゜)v。


正題

給出兩個n位數A,B。我們需要找到兩個最近的靠近A的n位數(第一個比A大或與A相等,第二個嚴格比A小),使得它們的十進制表示是B中所有數字的某個排列。


輸入輸出(需要自取)

Input

輸入文件closest.in包含2行:
第1行為一個正整數A。
第1行為一個正整數B。
(A,B均為n位的正整數)

Output

輸出文件closest.out共有2行。
第一行:最小的不比A小的n位數,沒有前導0,包含B中的所有字符,以某一順序排列。如果這樣的數不存在,那么輸出0。
第二行:最大的比A小的n位數,沒有前導0,包含B中的所有字符,以某一順序排列。如果這樣的數不存在,那么輸出0。

Sample Input

輸入樣例1

3075
6604

輸入樣例2

3000203
4562454

Sample Output

輸出樣例1

4066
0

輸出樣例2

4244556
2655444


解題思路

B用桶存,然后分兩段輸出,一段是相等的和第一個不相等(大的或小的),第二段是將桶剩下的輸出(從大到小或從小到大),然后用dfs更正。


代碼

#include<cstdio> #include<iostream> #include<algorithm> using namespace std; int c[61],f[10],t[10],p[61]; char read; int n,maxn,mark; bool flag,flag2,ok; void dfs(int i)//深搜 {if (i>n)//全部等于的情況{flag=true;ok=true;for (int j=1;j<=n;j++) printf("%d",p[j]);return;}flag2=false;for (int j=c[i];j<=9;j++){if (f[j]>0){p[i]=j;f[j]--;flag2=true;if (j>c[i])//找到一個了{flag=true;break;}dfs(i+1);//深搜if (ok) return;f[j]++;//回溯}}if (flag){for (int j=1;j<=i;j++) printf("%d",p[j]);//輸出第一部分ok=true;return;}if (!flag2)//找不到了{return;} } void dfs2(int i)//相仿,看上面↑ {if (i>n){ok=true;return;}flag2=false;for (int j=c[i];j>=0;j--){if (t[j]>0 && (i!=1 || j!=0)){p[i]=j;t[j]--;flag2=true;if (j<c[i]){flag=true;break;}dfs2(i+1);if (ok) return;}}if (flag){for (int j=1;j<=i;j++) printf("%d",p[j]);ok=true;return;}if (!flag2){return;} } int main() {while ((read=getchar())!='\n'){n++;c[n]=read-48;//輸入}for (int i=1;i<=n;i++) {cin>>read;t[read-48]++;f[read-48]++;}//輸入flag=false;ok=false;dfs(1);//搜if (!flag && !flag2) printf("0");//找不到else for (int i=0;i<=9;i++)for (int j=1;j<=f[i];j++)printf("%d",i);//輸出第二段printf("\n");flag=false;dfs2(1);if (!flag && !flag2) printf("0");else if(flag2 && !flag){if (prev_permutation(p+1,p+1+n))//如果連段可以全部相等就輸出上一個排列for (int j=1;j<=n;j++) printf("%d",p[j]);}else for (int i=9;i>=0;i--)for (int j=1;j<=t[i];j++)printf("%d",i);//輸出第二段 }

總結

以上是生活随笔為你收集整理的【2018.3.10】模拟赛之一-ssl2574Closest【深搜】的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。