台州学院第七届“星峰杯”大学生程序设计竞赛

来源:互联网 发布:淘宝搜索算法 编辑:程序博客网 时间:2024/04/30 00:15

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;elser = 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;elsel = 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

原创粉丝点击