题目来源:NAIPC2018
D: Missing Gnomes
题目描述
A family of n gnomes likes to line up for a group picture. Each gnome can be uniquely identified by a number 1..n written on their hat.
Suppose there are 5 gnomes. The gnomes could line up like so: 1, 3, 4, 2, 5.
Now, an evil magician will remove some of the gnomes from the lineup and wipe your memory of the order of the gnomes. The result is a subsequence, perhaps like so: 1, 4, 2.
He then tells you that if you ordered all permutations of 1..n in lexicographical order, the original sequence of gnomes is the first such permutation which contains the remaining subsequence. Your task is to find the original sequence of gnomes.
Suppose there are 5 gnomes. The gnomes could line up like so: 1, 3, 4, 2, 5.
Now, an evil magician will remove some of the gnomes from the lineup and wipe your memory of the order of the gnomes. The result is a subsequence, perhaps like so: 1, 4, 2.
He then tells you that if you ordered all permutations of 1..n in lexicographical order, the original sequence of gnomes is the first such permutation which contains the remaining subsequence. Your task is to find the original sequence of gnomes.
输入
Each input will consist of a single test case. Note that your program may be run multiple times on different inputs. Each test case will begin with a line with two integers n and then m (1 ≤ m ≤ n ≤ 105 ), where n is the number of gnomes originally, and m is the number of gnomes remaining after the evil magician pulls his trick. Each of the next m lines will contain a single integer g(1 ≤ g ≤ n). These are the remaining gnomes, in order. The values of g are guaranteed to be unique.
输出
Output n lines, each containing a single integer, representing the first permutation of gnomes that could contain the remaining gnomes in order.
样例输入
5 3
1
4
2
样例输出
1 3 4 2 5
题意:给你一个n一个k k个数 找包含这k个数的长度为n的序列 要求这k个数给定的顺序不变 剩下的填入后 字典序最小
解析:找没出现的填在给的数(比它大的)后
栗子:给了1 4 2 要填3 5
3 5
代码:
#includeusing namespace std; typedef long long ll; bool check[100050]; int uncheck[100050]; int op[100050]; int ans[100050]; int main() { //freopen("in.txt","r",stdin); int n,m; while(scanf("%d %d",&n,&m)!=EOF) { memset(check,0,sizeof(check)); for(int i=1;i<=m;i++) { scanf("%d",&op[i]); check[op[i]]=1; } int k=1; for(int i=1;i<=n;i++) { if(check[i]==0) { uncheck[k++]=i; } } k=1; for(int i=1;i<=m;i++) { if(op[i]>uncheck[k]) { while(op[i]>uncheck[k]&&k<=n-m) { printf("%d\n",uncheck[k]); // ans[cnt++]=uncheck[k]; k++; } } printf("%d\n",op[i]); } for(;k<=n-m;k++) { printf("%d\n",uncheck[k]); } } return 0; }
H: Recovery
题目描述
Consider an n × m matrix of ones and zeros. For example, this 4 × 4:
1 1 1 1
0 1 1 1
0 1 1 1
0 1 1 0
We can compute even parity for each row, and each column. In this case, the row parities are [0, 1, 1, 0] and the column parities are [1, 0, 0, 1] (the parity is 1 if there is an odd number of 1s in the row or column, 0 if the number of 1s is even). Note that the top row is row 1, the bottom row is row n, the leftmost column is column 1, and the rightmost column is column m.
Suppose we lost the original matrix, and only have the row and column parities. Can we recover the original matrix? Unfortunately, we cannot uniquely recover the original matrix, but with some constraints, we can uniquely recover a matrix that fits the bill. Firstly, the recovered matrix must contain as many 1’s as possible. Secondly, of all possible recovered matrices with the most 1’s, use the one which has the smallest binary value when you start with row 1, concatenate row 2 to the end of row 1, then append row 3, row 4, and so on.
1 1 1 1
0 1 1 1
0 1 1 1
0 1 1 0
We can compute even parity for each row, and each column. In this case, the row parities are [0, 1, 1, 0] and the column parities are [1, 0, 0, 1] (the parity is 1 if there is an odd number of 1s in the row or column, 0 if the number of 1s is even). Note that the top row is row 1, the bottom row is row n, the leftmost column is column 1, and the rightmost column is column m.
Suppose we lost the original matrix, and only have the row and column parities. Can we recover the original matrix? Unfortunately, we cannot uniquely recover the original matrix, but with some constraints, we can uniquely recover a matrix that fits the bill. Firstly, the recovered matrix must contain as many 1’s as possible. Secondly, of all possible recovered matrices with the most 1’s, use the one which has the smallest binary value when you start with row 1, concatenate row 2 to the end of row 1, then append row 3, row 4, and so on.
输入
Each input will consist of a single test case. Note that your program may be run multiple times on different inputs. Each test case will consist of exactly two lines. The first line will contain a string R (1 ≤ |R| ≤ 50), consisting only of the characters 0 and 1. These are the row parities, in order.
The second line will contain a string C (1 ≤ |C| ≤ 50), consisting only of the characters 0 and 1.
These are the column parities, in order.
The second line will contain a string C (1 ≤ |C| ≤ 50), consisting only of the characters 0 and 1.
These are the column parities, in order.
输出
If it is possible to recover the original matrix with the given constraints, then output the matrix as |R| lines of exactly |C| characters, consisting only of 0’s and 1’s. If it is not possible to recover the original matrix, output −1.
样例输入
0110
1001
样例输出
1111 0111 1110 1111
题意:给你两个01字符串,第一行第i个 0代表第i行有偶数个1 1代表第i行有奇数个1。第二行 对应代表列的奇偶
另外的两个条件 1.1的个数尽量多 2.若很多情况1的个数相同,从第一行到第n行,选二进制最小的那个(优先行数小的)
解析:
1.记录下答案是几列、几行的矩阵,并都初始化为1。
2.记录哪一行不满足条件,初始化的矩阵1的个数的奇偶与给定的不同(说明这行需要加0使条件符合) cnt1个
3.如第2步记录列的 (与2同) cnt2个
4.若cnt1!=cnt2 那么就要优先往左上角补 (若cnt1然后sort 贪心一下
将矩阵该变的变为0 就可以输出了
参考:http://www.cnblogs.com/tingtin/p/9487642.html
代码:
#includeusing namespace std; int main() { char s1[55]; char s2[55]; while(scanf("%s%s",s1,s2)==2) { int n = strlen(s1); int m = strlen(s2); int x = n%2; int y = m%2; int a[105],b[105]; int cnt1 = 0,cnt2 = 0; for(int i=0; i ) { int tmp = s1[i]-'0'; if(tmp!=y) a[cnt1++] = i; } for(int i=0; i ) { int tmp = s2[i]-'0'; if(tmp!=x) b[cnt2++] = i; } // for(int i=0;i // { // cout<// } if((cnt1+cnt2)%2!=0) { printf("-1\n"); continue; } while(cnt1<cnt2) a[cnt1++] = 0; while(cnt2<cnt1) b[cnt2++] = 0; int Map[55][55]; for(int i=0; i = 1; } } sort(a,a+cnt1); sort(b,b+cnt2); for(int i=0; i) { for(int j=0; j) { Map[i][j] ) { Map[a[i]][b[i]] = 0; } for(int i=0; i ) { for(int j=0; j ) { cout<<Map[i][j]; } cout<<endl; } } return 0; }