D 链上LIS
题意:
现在有一个数列(1~n),给你两个操作
1.把倒数第二个移到第一个位置
2.把第一个移到最后一个位置
问你最少要做多少操作才能让这个数列变成有序的。
思路:
如果把这个数列看成一个收尾相接的环,环上有个指针,那么这个1操作就是交替相邻元素的位置,这个2操作就是更换指针的位置。
所以最小操作数就是数列长度 - 链上LIS。
复杂度O(n^3)
注意因为是首尾连成链,所以数组有可能要开两倍。
#include <bits/stdc++.h>
using namespace std;
const int maxn = 2100;
int n, p[maxn], a[maxn], dp[maxn];
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
cout.precision(10);
cout << fixed;
#ifdef LOCAL_DEFINE
freopen("input.txt", "r", stdin);
#endif
cin >> n;
for (int i = 1; i <= n; ++i) {
cin >> p[i];
p[i + n] = p[i];
}
int ans = INT_MAX;
for (int i = 1; i <= n; ++i) {
for (int j = 0; j < n; ++j) {
a[j] = p[i + j];
}
int lis = 1;
for (int j = 0; j < n; ++j) {
dp[j] = 1;
for (int k = 0; k < j; ++k) {
if (a[j] > a[k]) dp[j] = max(dp[j], dp[k] + 1);
}
lis = max(lis, dp[j]);
}
ans = min(ans, n - lis);
}
cout << ans << '\n';
#ifdef LOCAL_DEFINE
cerr << "Time elapsed: " << 1.0 * clock() / CLOCKS_PER_SEC << " s.\n";
#endif
return 0;
}
E 高精度
题意:
加粗样式step:1.for(int i=1; i<=n; ++i) b[i]=a[p[i]]; 2. for(int i=1; i<=n; ++i) b[i]=a[i]
最后要变为sorted arrary
问你有多少种数组最后能得到相同的sorted array
思路:
求所有cycle的lcm。
java代码待补。
import math
n = int(input())
a = [1]
vis = [0] * (n + 1)
temp = input().split()
for x in temp :
tx = int(x)
a.append(tx)
ans = 1
for i in range(1, 1 + n) :
u = i
cnt = 0
if vis[u] == 1 : continue
while vis[u] == 0 :
vis[u] = 1;
cnt += 1
u = a[u]
ans = (ans * cnt) // math.gcd(ans, cnt)
print(ans)
F 签到
就按他要求的输出就行了。
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const ll maxn = 120;
ll n, d[maxn], vis[maxn];
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
cout.precision(10);
cout << fixed;
#ifdef LOCAL_DEFINE
freopen("input.txt", "r", stdin);
#endif
cin >> n;
ll maxx = -1;
for (ll i = 1; i <= n; ++i) {
cin >> d[i];
maxx = max(d[i], maxx);
}
memset(vis, 0, sizeof(vis));
for (ll i = 1; i <= n; ++i) {
if (maxx == d[i]) {
vis[i] = 1;
}
}
for (ll i = 1; i <= n; ++i) {
cout << '+';
ll temp = (50 * d[i] + maxx - 1) / maxx;
//cerr << "temp : " << temp << endl;
for (int j = 0; j < temp; ++j) cout << '-';
cout << '+' << '\n';
cout << '|';
for (int j = 0; j < temp - 1; ++j) cout << ' ';
if (vis[i] == 1) cout << '*';
else {
if (temp > 0) cout << ' ';
}
cout << '|';
cout << d[i] << '\n';
cout << '+';
for (int j = 0; j < temp; ++j) cout << '-';
cout << '+' << '\n';
}
#ifdef LOCAL_DEFINE
cerr << "Time elapsed: " << 1.0 * clock() / CLOCKS_PER_SEC << " s.\n";
#endif
return 0;
}
I 签到
harder math problem
题意:
有一个矩阵,里面放1, 2,3,规定每个1旁边至少要有一个2和3。现在问你最多能放多少个1。
思路
(i+j)%3的点交错放2,3。答案是2/3。
#include<bits/stdc++.h>
using namespace std;
int main(){
cout<<"0.666667"<<'\n';
return 0;
}