T1:
裸模拟一发,枚举k还原密码即可
#include<iostream>
#include<cstdio>
#include<vector>
#include<algorithm>
#include<stack>
#include<cstdlib>
#include<cstring>
#include<cmath>
using namespace std;
const int maxn = 1E6 + 10;
typedef double DB;
const DB eps = 1E-10;
DB s = 1E18,x[26],p[26],tot;
char ch[maxn],t,ans[maxn],now[maxn];
int len,kt;
bool Judge(char cc)
{
if ('a' <= cc && cc <= 'z') return 1;
if ('A' <= cc && cc <= 'Z') return 1;
return 0;
}
void Work(int k)
{
for (int i = 1; i <= len; i++)
if (Judge(ch[i])) {
int y;
if ('a' <= ch[i] && ch[i] <= 'z') y = ch[i] - 'a';
else y = ch[i] - 'A';
int orz = y;
if (orz >= k) orz -= k;
else orz = orz + 26 - k;
char o;
if ('a' <= ch[i] && ch[i] <= 'z') o = orz + 'a';
else o = orz + 'A';
now[i] = o;
x[orz] += 1;
}
else now[i] = ch[i];
}
int main()
{
#ifdef DMC
freopen("DMC.txt","r",stdin);
#else
freopen("decode.in","r",stdin);
freopen("decode.out","w",stdout);
#endif
for (int i = 0; i < 26; i++) cin >> p[i]; getchar();
while (scanf("%c",&t) != -1) {
ch[++len] = t;
if (Judge(t)) tot += 1;
}
for (int k = 0; k < 26; k++) {
for (int i = 0; i < 26; i++) x[i] = 0;
Work(k);
DB s2 = 0;
for (int i = 0; i < 26; i++) {
DB T = p[i] - x[i]/tot;
s2 += T*T;
}
if (s2 < s) {
s = s2;
for (int i = 1; i <= len; i++) ans[i] = now[i];
}
}
for (int i = 1; i <= len; i++) printf("%c",ans[i]);
return 0;
}
没时间调试。。。编写时存在失误
二分+暴力判断,注意奇数和偶数情况要分开讨论
#include<iostream>
#include<cstdio>
#include<vector>
#include<algorithm>
#include<stack>
#include<cstdlib>
#include<cstring>
#include<cmath>
using namespace std;
const int maxn = 1E3 + 10;
int len,k,x[maxn],y[maxn];
char ch[maxn];
bool Judge(int now)
{
for (int i = 0; i < len; i++)
if (i + now <= len) {
int L = i,R = i + now - 1,sum = 0;
bool flag = 1;
while (L < R) {
if (ch[L] != ch[R]) ++sum;
++L; --R;
if (sum > k) {flag = 0; break;}
}
if (flag) return 1;
}
return 0;
}
int main()
{
#ifdef DMC
freopen("DMC.txt","r",stdin);
#else
freopen("palindrome.in","r",stdin);
freopen("palindrome.out","w",stdout);
#endif
scanf("%s",ch);
cin >> k;
len = strlen(ch);
int rx,ry; x[1] = 1; y[1] = 0;
for (rx = 2; ; rx++) {
x[rx] = x[rx-1] + 2;
if (x[rx] > len) {--rx; break;}
}
for (ry = 2; ; ry++) {
y[ry] = y[ry-1] + 2;
if (y[ry] > len) {--ry; break;}
}
int L,R; L = 1,R = rx;
while (R - L > 1) {
int mid = (L+R) >> 1;
if (Judge(x[mid])) L = mid;
else R = mid;
}
int ans = 0;
if (Judge(x[R])) ans = x[R];
else ans = x[L];
L = 1,R = ry;
while (R - L > 1) {
int mid = (L+R) >> 1;
if (Judge(y[mid])) L = mid;
else R = mid;
}
if (Judge(y[R])) ans = max(ans,y[R]);
else ans = max(ans,y[L]);
cout << ans;
return 0;
}
T3:
f[i]:以位置i结尾的最长信任链长
g[i]:以当前P值i结尾的最长信任链长
每次转移枚举1~100判断是否为约数
#include<iostream>
#include<cstdio>
#include<vector>
#include<algorithm>
#include<stack>
#include<cstdlib>
#include<cstring>
#include<cmath>
using namespace std;
const int maxn = 1E5 + 10;
int n,p[maxn],f[maxn],MAX[maxn];
int main()
{
#ifdef DMC
freopen("DMC.txt","r",stdin);
#else
freopen("chain.in","r",stdin);
freopen("chain.out","w",stdout);
#endif
cin >> n;
for (int i = 1; i <= n; i++) scanf("%d",&p[i]),f[i] = 1;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= 100; j++) {
if (i % j != 0) continue;
f[i] = max(f[i],MAX[j] + 1);
}
MAX[p[i]] = max(MAX[p[i]],f[i]);
}
int ans = 0;
for (int i = 1; i <= n; i++) ans = max(ans,f[i]);
cout << ans;
return 0;
}
一开始没看清题意。。
直接枚举1~100每个数的约数,这样在编号递增时出错
T4:
搜索搜索搜索优先级显然是A>B>C>D>E
#include<iostream>
#include<cstdio>
#include<vector>
#include<algorithm>
#include<stack>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<queue>
using namespace std;
const int dx[4] = {0,1,0,-1};
const int dy[4] = {-1,0,1,0};
struct P{
int x,y;
};
int n,m,p[14][14],t[6],dis[14][14];
bool vis[14][14];
char ans[10],ch[20],nw[20];
queue <P> q;
void Work()
{
while (!q.empty()) {
P k = q.front(); q.pop();
for (int i = 0; i < 4; i++) {
int xx = k.x + dx[i];
int yy = k.y + dy[i];
while (0 <= xx && xx <= n+1 && 0 <= yy && yy <= m+1) {
if (p[xx][yy] && p[xx][yy] != p[k.x][k.y] && p[k.x][k.y]) break;
if (dis[xx][yy] == 1000) {
dis[xx][yy] = dis[k.x][k.y] + 1;
if (!p[xx][yy]) q.push((P){xx,yy});
}
if (p[xx][yy]) break;
xx += dx[i];
yy += dy[i];
}
}
}
}
int Judge(int X1,int Y1,int X2,int Y2)
{
for (int i = 0; i <= n+1; i++)
for (int j = 0; j <= m+1; j++)
dis[i][j] = 1000;
q.push((P){X1,Y1}); dis[X1][Y1] = 0;
Work();
return dis[X2][Y2];
}
bool dfs(int now)
{
if (now - 1 == (n*m)/2) {
int flag = 0;
for (int i = 1; i <= (n*m)/2; i++) {
if (nw[i] < ans[i]) {flag = 1; break;}
if (nw[i] > ans[i]) break;
}
if (flag) for (int i = 1; i <= (n*m)/2; i++) ans[i] = nw[i];
return 1;
}
int c[6],x[6][7],y[6][7];
memset(c,0,sizeof(c));
memset(x,0,sizeof(x));
memset(y,0,sizeof(y));
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++)
if (p[i][j]) {
++c[p[i][j]];
x[p[i][j]][c[p[i][j]]] = i;
y[p[i][j]][c[p[i][j]]] = j;
}
for (int i = 1; i <= 5; i++) {
bool flag = 0;
for (int j = 1; j < c[i]; j++)
for (int k = j + 1; k <= c[i]; k++)
if (Judge(x[i][j],y[i][j],x[i][k],y[i][k]) <= 3) {
p[x[i][j]][y[i][j]] = 0;
p[x[i][k]][y[i][k]] = 0;
nw[now] = i - 1 + 'A';
if (dfs(now+1)) flag = 1;
p[x[i][j]][y[i][j]] = i;
p[x[i][k]][y[i][k]] = i;
}
if (flag) return 1;
}
return 0;
}
int main()
{
#ifdef DMC
freopen("DMC.txt","r",stdin);
#else
freopen("game.in","r",stdin);
freopen("game.out","w",stdout);
#endif
cin >> n >> m;
for (int i = 1; i <= 10; i++) ans[i] = 'Z';
for (int i = 1; i <= n; i++) {
scanf("%s",ch);
for (int j = 1; j <= m; j++) {
p[i][j] = ch[j-1] - 'A' + 1;
++t[p[i][j]];
}
}
for (int i = 1; i <= 5; i++)
if (t[i] % 2 == 1) {printf("Game over."); return 0;}
if (dfs(1)) {
for (int i = 1; i <= (n*m)/2; i++)
printf("%c",ans[i]);
}
else printf("Game over.");
return 0;
}
开始写的时候。。你最早搜的答案不一定对
BABACD与BAABCD
两对A删去的顺序不同直接影响到结果
所以即使当前判到一组答案也不能马上return 如代码使用flag判断