A.
题意: 给定1~n的数,输出一种有k个峰值的排列
解法:
1.首先观察易推出当k > (n - 1) / 2时不存在
2, 当k满足条件,由样例可以观察得出:1, n位置不算峰值,故考虑从2 ~ n - 1的位置构造答案,只需对原2~n - 1的序列相邻的数进行一次位置交换即可诞生一个峰值,生成所有峰值后将剩余的数输出即可
AC代码
#include <bits/stdc++.h>
using namespace std;
#define IO std::ios::sync_with_stdio(false); cin.tie(0)
#define ll long long
#define ull unsigned long long
#define SZ(x) ((int)(x).size())
#define all(x) (x).begin(), (x).end()
#define rep(i, l, r) for (int i = l; i <= r; ++i)
#define per(i, l, r) for (int i = l; i >= r; --i)
#define mset(s, _) memset(s, _, sizeof(s))
#define mcpy(s, _) memcpy(s, _, sizeof(s))
#define pb push_back
#define pii pair <int, int>
#define vi vector<int>
#define vpii vector<pii>
#define mp(a, b) make_pair(a, b)
#define debug system("pause")
#define pll pair <ll, ll>
#define fir first
#define sec second
#define inf 0x3f3f3f3f
#define pline cout << endl << endl
inline int lowbit(int x) {return x & -x;}
template< typename T > inline void get_min(T &x, T y) {if(y < x) x = y;}
template< typename T > inline void get_max(T &x, T y) {if(x < y) x = y;}
inline int read() {
int x = 0, f = 0; char ch = getchar();
while (!isdigit(ch)) f |= ch == '-', ch = getchar();
while (isdigit(ch)) x = 10 * x + ch - '0', ch = getchar();
return f ? -x : x;
}
template<typename T> inline void print(T x) {
if (x < 0) putchar('-'), x = -x;
if (x >= 10) print(x / 10);
putchar(x % 10 + '0');
}
template<typename T> inline void print(T x, char let) {
print(x), putchar(let);
}
const int N = 2e5 + 10, mod = 1e9 + 7;
int t, n, m;
int main() {
cin >> t;
while(t -- ) {
cin >> n >> m;
if(m > (n - 1) / 2) {
puts("-1"); continue;
}
cout << "1 ";
int num = 1;
rep(i, 1, m) {
cout << num + 2 << " " << num + 1 << " ";
num += 2;
}
for(int i = num + 1; i <= n; i ++ ) {
cout << i << ' ';
}
cout << endl;
}
return 0;
}
B
题意:
解法: 有点玄学,之后再补题QwQ
C
题意:给定数字n与m个操作,每次操作可以使得n的每一位数均+1,求m次操作后n有多少位数
解法:分析可知任意数字n的每一位数进行m次操作时都是相互独立互不影响的,故可以考虑利用dp手段预处理处一位数0~9的经过m次操作后的位数,最后进行查表即可
dp[i][j]:表示数字i经过j次操作后的位数
对于i = 0~8,因为不会发生进位,故dp[i][j] = dp[i + 1][j - 1];
对于i = 9,会发生进位,故dp[i][j] = dp[1][j - 1] + dp[0][j - 1];
AC代码(此题输入用cin被t了QWQ,dp也不能开ll)
注意:
对于这类状态转移方程中当前状态来自于i + 1这种后面的状态的处理方式
1.将dp数组的维度含义呼唤处理 即dp[i][j]:表示数字j经过i次操作后的位数
2.改变递推循环次序
#include <bits/stdc++.h>
using namespace std;
#define IO std::ios::sync_with_stdio(false); cin.tie(0)
#define ll long long
#define ull unsigned long long
#define SZ(x) ((int)(x).size())
#define all(x) (x).begin(), (x).end()
#define rep(i, l, r) for (int i = l; i <= r; ++i)
#define per(i, l, r) for (int i = l; i >= r; --i)
#define mset(s, _) memset(s, _, sizeof(s))
#define mcpy(s, _) memcpy(s, _, sizeof(s))
#define pb push_back
#define pii pair <int, int>
#define vi vector<int>
#define vpii vector<pii>
#define mp(a, b) make_pair(a, b)
#define debug system("pause")
#define pll pair <ll, ll>
#define fir first
#define sec second
#define inf 0x3f3f3f3f
#define pline cout << endl << endl
inline int lowbit(int x) {return x & -x;}
template< typename T > inline void get_min(T &x, T y) {if(y < x) x = y;}
template< typename T > inline void get_max(T &x, T y) {if(x < y) x = y;}
inline int read() {
int x = 0, f = 0; char ch = getchar();
while (!isdigit(ch)) f |= ch == '-', ch = getchar();
while (isdigit(ch)) x = 10 * x + ch - '0', ch = getchar();
return f ? -x : x;
}
template<typename T> inline void print(T x) {
if (x < 0) putchar('-'), x = -x;
if (x >= 10) print(x / 10);
putchar(x % 10 + '0');
}
template<typename T> inline void print(T x, char let) {
print(x), putchar(let);
}
const int N = 2e5 + 10, mod = 1e9 + 7;
int t, n, m;
int dp[15][N];
int main() {
cin >> t;
rep(i, 0, 9) dp[i][0] = 1;
rep(j, 1, 200000) { //改变递推循环次序
rep(i, 0, 9) {
if(i >= 0 && i <= 8) dp[i][j] = dp[i + 1][j - 1];
if(i == 9) dp[i][j] = (dp[1][j - 1] + dp[0][j - 1]) % mod;
}
}
while(t -- ) {
scanf("%d%d", &n, &m);
ull ans = 0;
while(n) {
int x = n % 10;
ans = (ans + dp[x][m]) % mod;
n /= 10;
}
cout << ans << endl;
}
return 0;
}