8.11 2020 Multi-University Training Contest 7题解及补题
目录
8.11 2020 Multi-University Training Contest 7题解及补题
比赛过程
这场1009签到还可以,很可惜没有做出第二个题,1010其实有些思路,没有写出来,码力弱
题解
A
题意
解法
代码
//将内容替换成代码
B
题意
解法
代码
//将内容替换成代码
C
题意
解法
代码
//将内容替换成代码
D
题意
解法
代码
//将内容替换成代码
E
题意
解法
代码
//将内容替换成代码
F
题意
解法
代码
//将内容替换成代码
G
题意
解法
代码
//将内容替换成代码
H
题意
解法
代码
//将内容替换成代码
I Increasing and Decreasing
题意
输入n,x,y三个数,能否构造一个长度为n的全排列,使得最长上升子序列的长度为x,最长下降子序列的长度为y。若能构造,输出YES和这个序列。不能,则输出NO。
解法
可以把n分为若干个长度为y的倒序块,然后判断前面正序的数字是否够x个,如果够则直接输出,否则,把右侧的倒序块一个个转变为正序即可,如果最后一个倒序块被改变,就输出NO。
代码
#include <bits/stdc++.h>
#define IO ios::sync_with_stdio(0), cin.tie(0)
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int maxn = 1e5 + 5;
const int inf = ~0u >> 1;
typedef pair<int, int> P;
#define REP(i, a, n) for (int i = a; i < (n); ++i)
#define PER(i, a, n) for (int i = (n)-1; i >= a; --i)
const ll mod = 1e9 + 7;
int ans[maxn];
int main() {
IO;
int t;
cin >> t;
while (t--) {
int n, x, y;
cin >> n >> x >> y;
if (x == 1 || y == 1) {
if (x + y != n + 1) {
cout << "NO" << endl;
continue;
} else {
cout<<"YES"<<endl;
if (x == n) {
REP(i, 1, n + 1) {
if (i != 1) cout << ' ';
cout << i;
}
} else {
PER(i, 1, n + 1) {
if (i != n) cout << ' ';
cout << i;
}
}
cout << endl;
continue;
}
} else {
if (x + y - 1 > n) {
cout << "NO" << endl;
continue;
}
cout<<"YES"<<endl;
int sum = 0;
int num = n;
PER(i, 1, x + 1) {
int t = min(n - sum - (i - 1), y);
sum += t;
int tt = 1;
//cout << "t = " << t << endl;
PER(j, num - t + 1, num + 1) {
ans[n - sum + tt] = j;
//cout << "ans[" << n - sum + tt << "] = " << j << endl;
tt++;
}
num -= t;
}
REP(i, 1, n + 1) {
if (i != 1) cout << ' ';
cout << ans[i];
}
cout << endl;
}
}
return 0;
}
J Jogging
题意
在一个二维平面上有一个初始点(x,y),规定“好点”是满足gcd(x,y)>1,现在从点(x,y)开始,
每一次都能等概率的选择:
1.去周围八个方向中的“好点”
2.停留在原地不动
问当走无穷多次步数之后,能够从点(x,y)出发之后回到点(x,y)的概率是多少。
解法
计算答案的时候,需要用到一个结论 (s的度数+1)/(整张图的总度数+n),在本题中如果当前点和
y=x这条直线不连通,那么联通块大小也不会很大,否则由于y=x无限长,无穷步之后回到s的概率为0
代码
#include <bits/stdc++.h>
#define rep(i, n) for(int i = 0; i < (int)(n); i ++)
#define rep1(i, n) for(int i = 1; i <= (int)(n); i ++)
#define MP make_pair
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
const int MOD = 998244353;
map<pair<LL, LL>, int> vis;
int cnt;
LL gcd(LL u, LL v)
{
return v == 0 ? u : gcd(v, u % v);
}
bool dfs(LL x, LL y)
{
if(x == y) return true;
if(vis.find(MP(x, y)) != vis.end()) return false;
vis[MP(x, y)] = 1;
cnt ++;
if(gcd(x, y + 1) != 1) {
if(dfs(x, y + 1)) return true;
vis[MP(x, y)] ++;
cnt ++;
}
if(gcd(x + 1, y) != 1) {
if(dfs(x + 1, y)) return true;
vis[MP(x, y)] ++;
cnt ++;
}
if(gcd(x, y - 1) != 1) {
if(dfs(x, y - 1)) return true;
vis[MP(x, y)] ++;
cnt ++;
}
if(gcd(x - 1, y) != 1) {
if(dfs(x - 1, y)) return true;
vis[MP(x, y)] ++;
cnt ++;
}
if(gcd(x + 1, y + 1) != 1) {
if(dfs(x + 1, y + 1)) return true;
vis[MP(x, y)] ++;
cnt ++;
}
if(gcd(x + 1, y - 1) != 1) {
if(dfs(x + 1, y - 1)) return true;
vis[MP(x, y)] ++;
cnt ++;
}
if(gcd(x - 1, y - 1) != 1) {
if(dfs(x - 1, y - 1)) return true;
vis[MP(x, y)] ++;
cnt ++;
}
if(gcd(x - 1, y + 1) != 1) {
if(dfs(x - 1, y + 1)) return true;
vis[MP(x, y)] ++;
cnt ++;
}
return false;
}
void solve()
{
LL x, y;
scanf("%lld%lld", &x, &y);
vis.clear();
cnt = 0;
if(dfs(x, y)) printf("0/1\n");
else {
int c0 = vis[MP(x, y)], c1 = cnt;
int g = gcd(c0, c1);
printf("%d/%d\n", c0 / g, c1 / g);
}
}
int main()
{
int T;
scanf("%d", &T);
while(T --) solve();
return 0;
}
K
题意
解法
代码
//将内容替换成代码

浙公网安备 33010602011771号