hdu5671 Matrix
思路
* 所有操作都是整行或整列,所以矩形的两个维度可以独立处理
* 对于交换我们用一个映射表表示当前的第i行(列)是原矩形的第多少行(列),对于加数我们用一个数组记录原矩形第i行加了多少,为什么是原矩形呢?因为对现矩形的所有操作本质上是对原矩形的操作
代码
#include <bits/stdc++.h>
using namespace std;
const int N = 1e3 + 7;
int T, n, m, q, a[N][N], x[N], y[N], dx[N], dy[N], id, xx, yy;
void Case(int id) {
if (id == 1) swap(x[xx], x[yy]);
if (id == 2) swap(y[xx], y[yy]);
if (id == 3) dx[x[xx]] += yy;
if (id == 4) dy[y[xx]] += yy;
}
int main() {
//freopen("in.txt", "r", stdin);
cin >> T;
while (T--) {
cin >> n >> m >> q;
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
scanf("%d", a[i] + j);
}
}
for (int i = 0; i < n; i++) x[i] = i;
for (int i = 0; i < m; i++) y[i] = i;
memset(dx, 0, sizeof(dx));
memset(dy, 0, sizeof(dy));
while (q--) {
scanf("%d%d%d", &id, &xx, &yy);
xx--;
if (id <= 2) yy--;
Case(id);
}
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
int xx = x[i];
int yy = y[j];
printf("%d%c", a[xx][yy] + dx[xx] + dy[yy], j == m - 1? '\n' : ' ');
}
}
}
return 0;
}
hdu5672 String
思路
* 如果[l, r]表示的字串符合要求,那么[l, r+1]也符合要求
* 令f(l)表示[l, r]符合要求的最小的r,那么f(l)单调不降
代码
#include <bits/stdc++.h>
using namespace std;
int cnt[26], num, r, k, T, n;
char s[1234567];
long long ans;
int main() {
//freopen("in.txt", "r", stdin);
cin >> T;
while (T--) {
scanf("%s", s);
cin >> k;
n = strlen(s);
for (int i = 0; i < n; i++) s[i] -= 'a';
ans = num = r = 0;
memset(cnt, 0, sizeof(cnt));
for (int l = 0; l < n; l++) {
while (num < k && r < n) if (++cnt[s[r++]] == 1) num++;
if (num < k) break;
ans += n - r + 1;
if(--cnt[s[l]] == 0) num--;
}
cout << ans << endl;
}
return 0;
}
hdu5673 Robot
思路
* 要保证最后回到原点,那么向左走的步数必等于向右走的步数
* 假设有i秒原地不动,那么相当于有
n−2i
秒不是向左走就是向右走,同时要求不能出现在原点左边,这和进栈出栈序列总数是一样的,即方案总数是卡特兰数
* 答案等于
∑n2i=0C2in∗catalan(i)
代码
#include <bits/stdc++.h>
using namespace std;
const int mod = 1e9 + 7, N = 1e6 + 7;
long long ans;
int n, fac[N], invfac[N], cat[N], T;
long long powermod(long long a, int n, int m) {
long long ans = 1;
for (; n; n >>= 1) {
if (n & 1) ans = ans * a % m;
a = a * a % m;
}
return ans;
}
void init() {
fac[0] = invfac[0] = 1;
for (int i = 1; i < N; i++) {
fac[i] = (long long)fac[i - 1] * i % mod;
invfac[i] = invfac[i - 1] * powermod(i, mod - 2, mod) % mod;
}
cat[0] = cat[1] = 1;
for (int i = 2; i < N; i++) {
cat[i] = cat[i - 1] * (4ll * i - 2) % mod * powermod(i + 1, mod - 2, mod) % mod;
}
}
long long C(int n, int m) {
return (long long)fac[n] * invfac[m] % mod * invfac[n - m] % mod;
}
int work() {
ans = 0;
for (int i = 0; i * 2 <= n; i++) {
ans = (ans + C(n, i * 2) * cat[i]) % mod;
}
return ans;
}
int main() {
//freopen("in.txt", "r", stdin);
init();
cin >> T;
while (T--) {
cin >> n;
cout << work() << endl;
}
return 0;
}