4:3
谁是冠军?
floyd + 打印路径 以前一模一样的做到过 有木有 所以不解释了
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <math.h>
#include <string>
#include <queue>
#include <stack>
using namespace std;
int a[500][500];
int map[500][500];
const int inf = 100000000;
int n;
void floyd()
{
int k,i,j;
for(k = 1;k <= n; k++)
{
for(i = 1;i <= n; i++)
{
for(j = 1;j <= n; j++)
{
if(a[i][k] + a[k][j] < a[i][j])
{
a[i][j] = a[i][k] + a[k][j];
map[i][j] = map[i][k];
}
else if(a[i][k] + a[k][j] == a[i][j])
{
if(map[i][j] > map[i][k] && i != k)
{
map[i][j] = map[i][k];
}
}
}
}
}
}
int main()
{
int i,j,m;
while(scanf("%d",&n),n)
{
for(i = 1;i <= n; i++)
{
for(j = 1;j <= n; j++)
{
if(i == j)
{
a[i][j] = 0;
map[i][j] = j;
}
else
{
a[i][j] = inf;
map[i][j] = j;
}
}
}
for(i = 1;i <= n; i++)
{
scanf("%d",&m);
while(m--)
{
scanf("%d",&j);
a[i][j] = 1;
map[i][j] = j;
}
}
floyd();
scanf("%d",&m);
while(m--)
{
int x,y,k;
scanf("%d %d",&x,&y);
if(a[x][y] == inf)
printf("%d<%d",x,y);
else
{
printf("%d beats %d in %d times: %d",x,y,a[x][y],x);
k = x;
int cnt = 0;
while(k != y)
{
//cnt++;
//if(cnt > 10)
// break;
k = map[k][y];
printf(">%d",k);
}
}
puts("");
}
puts("");
}
return 0;
}
滚动特效
回文数列
LCS 转换成LIS
a数组数输入的
b数组是a的逆序
例如 a 1 1 2 2 b 2 2 1 1
首先因为每个数小于100
对于a数组每个数 找到b对应的位置 所以 1 对应 3 4 (b数组的1在3 和 4 的位置) 2 对应1 2
然后a数组就变成了 4 3 4 3 2 1 2 1 (每个数对应的位置要倒过来 比赛的时候没倒过来就错了 唉)
对新的 数组做对应的LIS即可 用2分求出LIS
学习自http://www.th7.cn/Program/cp/201208/88055.shtml
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <string>
#include <queue>
#include <stack>
using namespace std;
int a[20010];
int b[20010];
int dp[4000010];
int n;
int c[4000010];
int map[210];
void get()
{
int j,k,i;
vector <int> v[10010];
for(i = 0;i <= 200; i++)
{
if(map[i])
{
for(j = 1;j <= n; j++)
{
if(b[j] == i)
v[i].push_back(j);
}
}
}
k = 1;
for(i = 1;i <= n; i++)
{
int len = v[a[i]].size();
for(j = len - 1;j >= 0; j--)
{
c[k++] = v[a[i]][j];
}
}
//for(i = 1;i < k; i++)
// printf("%d ",c[i]);
//puts("");
int l ,r;
dp[1] = c[1];
int len = 1;
for(i = 2;i < k; i++)
{
l = 1;
r = len;
while(l <= r)
{
int m = (l + r) >> 1;
if(dp[m] < c[i])
l = m + 1;
else
r = m - 1;
}
if(len < l)
len++;
dp[l] = c[i];
}
printf("%d\n",n - len);
}
int main()
{
int t,i,j;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
memset(map,0,sizeof(map));
for(i = 1;i <= n; i++)
{
scanf("%d",&a[i]);
map[a[i]] = 1;
}
for(i = 1,j = n;i <= n; i++,j--)
{
b[j] = a[i];
}
get();
}
return 0;
}
My Trim Function
手机上网流量
计算面积
Poker Solitaire Game
发了发了
Jumping Castle
题目已经改了 走到下一个要消耗 2个城市差的绝对值的体力 求最小多少体力可以走完n*n个城市的一半
二分 + 深搜
参考http://www.cnblogs.com/luotinghao/p/3446330.html
差不多的给一题 http://acm.tzc.edu.cn/acmhome/problemdetail.do?&method=showdetail&id=4310
#include <stdio.h>
#include <string.h>
#include <math.h>
int n,flag,count;
int a[110][110];
int vis[110][110];
int dir[4][2] = {1,0,0,1,-1,0,0,-1};
int max;
void dfs(int x,int y,int m)
{
if(count * 2 >= n*n)
{
flag = 1;
return;
}
int i,xx,yy;
for(i = 0;i < 4; i++)
{
xx = x + dir[i][0];
yy = y + dir[i][1];
if(xx >= 1 && xx <= n && yy >= 1 && yy <= n && !vis[xx][yy] && (int)fabs(a[xx][yy] - a[x][y]) <= m)
{
count++;
vis[xx][yy] = 1;
dfs(xx,yy,m);
}
}
}
bool check(int m)
{
int i,j,k;
flag = 0;
memset(vis,0,sizeof(vis));
for(j = 1; j <= n; j++)
{
for(k = 1;k <= n; k++)
{
if(!vis[j][k])
{
count = 1;
vis[j][k] = 1;
dfs(j,k,m);
}
if(flag)
return true;
}
}
return false;
}
int erfen(int l,int r)
{
int m;
while(l < r)
{
m = (l + r) >> 1;
if(check(m))
r = m;
else
l = m + 1;
}
return r;
}
int main()
{
int i,j;
while(scanf("%d",&n)!=EOF)
{
max = 0;
for(i = 1;i <= n; i++)
{
for(j = 1;j <= n; j++)
{
scanf("%d",&a[i][j]);
if(max < a[i][j])
max = a[i][j];
}
}
printf("%d\n",erfen(0,max));
}
return 0;
}
The Longest Indentical Sub-String
后缀数组基本运用 求出后缀数组 和 LCP 在RMQ查询即可 查询线段树 或者ST
#include <iostream>
#include <string.h>
#include <algorithm>
#include <stdio.h>
#include <math.h>
using namespace std;
const int MAXN = 100010;
int sa[MAXN];
int t[MAXN],t2[MAXN],c[MAXN];
int rank[MAXN],height[MAXN];
int dp[MAXN][100];
void RMQ_init(int n)
{
int i,j,k;
for(i = 0; i < n; i++)
dp[i][0] = height[i+1];
k = (int) (log((double)n + 0.2) / log(2.0));
for(j = 1; j <= k; j++)
for(i = 0; i + (1 << j) - 1 <= n; i++)
dp[i][j] = min(dp[i][j-1],dp[i + (1 << (j-1))][j-1]);
}
int RMQ(int l,int r)
{
int k = 0;
k = (int) (log((double)(r - l + 1 + 0.2)) / log(2.0));
return min(dp[l][k],dp[r-(1<<k)+1][k]);
}
void build_sa(char *s,int n,int m)//倍增算法
{
int i,*x = t,*y = t2;
//基数排序
for(i = 0; i < m; i++)
c[i] = 0;
for(i = 0; i < n; i++)
c[x[i] = s[i]]++;
for(i = 1; i < m; i++)
c[i] += c[i-1];
for(i = n-1; i >= 0; i--)
sa[--c[x[i]]] = i;
for(int k = 1; k <= n; k <<= 1)
{
int p = 0;
//直接利用sa数组排序第二关键字
for(i = n-k; i < n; i++)
y[p++] = i;
for(i = 0; i < n; i++)
if(sa[i] >= k)
y[p++] = sa[i] - k;
//基数排序第一关键字
for(i = 0; i < m; i++)
c[i] = 0;
for(i = 0; i < n; i++)
c[x[y[i]]]++;
for(i = 0; i < m; i++)
c[i]+= c[i-1];
for(i = n-1; i >= 0; i--)
sa[--c[x[y[i]]]] = y[i];
//根据sa和y数组计算新的x数组
swap(x,y);
p = 1; x[sa[0]] = 0;
for(i = 1;i < n; i++)
x[sa[i]] = y[sa[i-1]] == y[sa[i]] && y[sa[i-1]+k] == y[sa[i]+k] ? p-1:p++;
if(p >= n)
break;
m = p;
}
}
void getHeight(char *s,int n)
{
int i,j,k = 0;
for(i = 1; i <= n; i++)
rank[sa[i]] = i;
for(i = 0; i < n; i++)
{
if(k)
k--;
int j = sa[rank[i]-1];
while(s[i+k] == s[j+k])
k++;
height[rank[i]] = k;
}
}
int main()
{
char s[MAXN];
int p1,p2,m,n,i,k;
while(gets(s))
{
n = strlen(s);
if(!n)
continue;
build_sa(s,n+1,200);
scanf("%d",&m);
getHeight(s,n);
RMQ_init(n);
while(m--)
{
scanf("%d %d",&p1,&p2);
if(rank[p1] > rank[p2])
swap(p1,p2);
printf("%d\n",RMQ(rank[p1],rank[p2]-1));
}
}
return 0;
}
A VS B