一道笔试题,做的很垃圾
给定相同位数为N的两个整形数A,B,其中B的每位数直接可以调整位置,我们要通过调整B中每位数的位置,找到一个B',使得B'为大于A的最小组合数。
如果找不到则返回-1,否则返回B'.
例如:
输入:
N=3
A=421
B=123
输出:-1
输入:
N=4
A=1234
B=1232
输出:1322
思路:首先将输入的两个数放入两个整形数组,a,b中,对数组b进行一个从小到大的排序处理。
1.对a,b数组进行一个按位比较,比较a[i],b[i],找到第一个i,使得a[i]!=b[i]
2.如果b[i]>a[i],可以直接返回b
3.如果a[i]>b[i],在数组b的[i+1,n-1]中找一个j,使得b[j]>=a[i],如果找不到,则i回退一步,i-1的位置a[i-1]=b[i-1],往后找第一个大于a[i-1]的数b[s],然后将b[s]的值置于i-1处,i-1后的数往后移。
4.如果找到b[j]>a[i],将b[j]的值置于i处,i到j处的值往后移。
5.如果找到b[j]=a[i],i++,重复2-4.
#include <iostream> #include<vector> #include<algorithm> using namespace std; void trans(vector<int> &b, int h, int s) { int te=b[h]; while(h>s) { b[h]=b[h-1]; h--; } b[s]=te; } int solut(const vector<int> &a, vector<int> &b, int n){ int i = 0; while(a[i] == b[i]){ cout<<a[i]<<" "<<b[i]<<endl; i++; } cout<<i<<endl; if(i >= n) return -1; int j = i + 1; while(a[i] > b[i]){ for(; j < n; j++){ if(b[j] > a[i]){//找到一个b[j]>a[i] trans(b, j, i); break; } else if(b[j] == a[i]){ trans(b, j, i); i++; break; } } while(j == n)//找不到一个比a[i]大的数,回退到i-1 { if(i == 0) return -1;//最后回退到0,没有找到比a[i]大的数,则返回-1 i--; int j = i + 1; while(j < n && b[j] <= a[i]){ j++; } if(j < n){ trans(b, j, i); break; } } sort(b.begin()+i+1, b.end());//在找到一个比a[i]大的数后,将b[i+1]-b[n-1]进行一个从小到大的排序 } return 0; } int main(){ int n; cin>>n; string s1, s2; cin>> s1>>s2; vector<int>a; vector<int>b; for(int i = 0; i < n; ++i){ int num1 = s1[i] - '0'; int num2 = s2[i] - '0'; a.push_back(num1); b.push_back(num2); } sort(b.begin(), b.end()); int s = solut(a, b, n); if(s == -1) cout<<-1<<endl; if(s == 0) { for(int i = 0; i < n; i++) cout<< b[i] <<" "; cout<<endl; } return 0; }