A. Strange Table
题意:给出n行m列,给出按列排序的编号,要求按行排序的编号。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
ll n, m, x;
int main()
{
int t;
cin >> t;
while (t -- )
{
scanf("%lld%lld%lld", &n, &m, &x);
ll xs, ys;
xs = x % n;
if (!xs) xs = n;
xs --;
xs *= m;
ys = (x - 1) / n;
ys ++;
printf("%lld\n", ys + xs);
}
return 0;
}
B. Partial Replacement
题意:用x代替号,保证两个x的距离不比k大,最后输出最小的替换次数。
特判 号1个和两个的情况。
要求最小次数,那么被替换的号和上一次被替换的号距离要最大。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int t, n, k;
char s[55];
int main()
{
cin >> t;
while (t -- )
{
scanf("%d%d", &n, &k);
cin >> s + 1;
int cnt = 0;
int st, en;
for (int i = 1; i <= n; i ++ )
{
if (s[i] == '*') ++ cnt;
}
for (int i = 1; i <= n; i ++ )
{
if (s[i] == '*')
{
st = i;
break;
}
}
for (int i = n; i >= 1; i -- )
{
if (s[i] == '*')
{
en = i;
break;
}
}
int ans = 0, now = st + k;
if (cnt == 1)
{
cout << '1' << endl;
continue;
}
else if (cnt == 2)
{
cout << '2' << endl;
continue;
}
else
{
while (now < en)
{
for (int i = now;; i -- )
if (s[i] == '*')
{
now = i;
ans ++;
break;
}
now += k;
}
}
cout << ans + 2 << endl;
}
return 0;
}
C. Double-ended Strings
晕,就直接暴力。
找出两个字符串中最长的相同字串长度就行。
学了一个substr,从i开始取k个长度的字符串。
#include <bits/stdc++.h>
using namespace std;
int main()
{
int t;
scanf("%d", &t);
while (t -- )
{
string a, b;
cin >> a >> b;
int lena = a.size();
int lenb = b.size();
//int ans = 1e9;
int res = 0;
int i ,j, k;
for (i = 0; i < lena; i ++ )
{
for (j = 0; j < lenb; j ++ )
{
for (k = 0; k < min(lena - i, lenb - j); k ++ )
{
//if (a.substr(i, k) == b.substr(j, k)) ans = min(ans, lena + lenb - 2 * k);
if (a[i + k] != b[j + k]) break;
}
res = max(res, k);
}
}
//cout << ans << endl;
cout << lena + lenb - 2 * res << endl;
}
return 0;
}
D. Epic Transformation
题意:不断地删掉两个不同的数字,直到无法继续删,要求最后剩下的数字最少,我们只要每次挑出当前数量最大的两个数各自删掉一个即可。用优先队列模拟。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int, int> PII;
const int N = 200010;
int a[N], vis[N];
int main()
{
int t, n;
priority_queue<int, vector<int>, less<int> > q;
cin >> t;
while (t -- )
{
scanf("%d", &n);
while (!q.empty()) q.pop();
memset(vis, 0, sizeof vis);
for (int i = 1; i <= n; i ++ ) scanf("%d", &a[i]);
sort(a + 1, a + 1 + n);
int idx = 1;
vis[idx] ++;
for (int i = 2; i <= n; i ++ )
{
if (a[i] == a[i - 1]) vis[idx] ++;
else vis[++ idx] ++;
}
for (int i = 1; i <= idx; i ++ ) q.push(vis[i]);
while (q.size() > 1)
{
int x = q.top(); q.pop();
int y = q.top(); q.pop();
x --, y -- ;
if (x) q.push(x);
if (y) q.push(y);
}
if (!q.empty()) printf("%d\n", q.top());
else puts("0");
}
return 0;
}
E. Restoring the Permutation
题意;用q[]数组来推出字典序最大和最小的p[]数组。
q[]为当前p[]的前辍的最大值。
我们能发现一个特性。当q[]数组中的数改动时,此位置的p[]组中的数即为当前p[]数组的数。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int t;
int n;
int arr[200002];
set<int> st;
stack<int> q;
int main(){
scanf("%d", &t);
while(t -- )
{
scanf("%d", &n);
for(int i = 1; i <= n; i ++ ) scanf("%d", &arr[i]);
for(int i=1; i<=n; i++) st.insert(i);
for(int i=1; i<=n; i++)
{
if(arr[i] != arr[i - 1]) printf("%d ", arr[i]), st.erase(arr[i]);
else printf("%d ", *st.begin()), st.erase(st.begin());
}
puts("");
while (!q.empty()) q.pop();
for (int i = 1; i <= n; i ++ )
{
if (arr[i] != arr[i - 1])
{
printf("%d ", arr[i]);
for (int j = arr[i - 1] + 1; j <= arr[i] - 1; j ++ ) q.push(j);
}
else
{
printf("%d ", q.top());
q.pop();
}
}
puts("");
}
}