南京某理工类高校机试题

并查集+kruskal+坐标处理

 1 const int MAXN=110;//最大点数
 2 const int MAXM=100005;//最大边数
 3 int F[MAXN];//并查集使用
 4 struct Node {
 5     int x;
 6     int y;
 7 } Point[1000];
 8 struct Edge {
 9     int u,v;
10     double w;
11 } edge[MAXM]; //存储边的信息,包括起点/终点/权值
12 int tol;//边数,加边前赋值为0
13 void addedge(int u,int v,double w) { //邻接矩阵的优化结构,kruskal单向路径就能做,没必要构造双向
14     edge[tol].u=u;
15     edge[tol].v=v;
16     edge[tol++].w=w;
17 }
18 bool cmp(Edge a,Edge b) {
19     //排序函数,讲边按照权值从小到大排序
20     return a.w<b.w;
21 }
22 int find(int x) {
23     if(F[x]==-1)
24         return x;
25     else
26         return
27             F[x]=find(F[x]);
28 }
29 double Kruskal(int n) { //传入点数,返回最小生成树的权值,如果不连通返回-1
30     memset(F,-1,sizeof(F));
31     sort(edge,edge+tol,cmp);
32     int cnt=0;//计算加入的边数
33     double ans=0;
34     for(int i=0; i<tol; i++) {
35         int u=edge[i].u;
36         int v=edge[i].v;
37         double w=edge[i].w;
38 
39         int t1=find(u);
40         int t2=find(v);
41         if(t1!=t2) {        //利用并查集改变顶点集合状态
42             ans+=w;
43             F[t1]=t2;
44             cnt++;
45         }
46         if(cnt==n-1)         //n个结点,n-1条边,所以只要合并n-1次即可
47             break;
48     }
49     if(cnt<n-1)
50         return -1;//不连通
51     else
52         return ans;
53 }
54 double Dis(int x1,int y1,int x2,int y2) {
55     return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
56 }
57 int main() {
58     int i,j;
59     int m;
60     double w;
61 
62     scanf("%d",&m);
63     for(i=1; i<=m; i++) {
64         scanf("%d %d",&Point[i].x,&Point[i].y);
65     }
66     for(i=1; i<=m; i++)
67         for(j=i+1; j<=m; j++) { //这样够造的就是有向图,减少了构造空间
68             w=Dis(Point[i].x,Point[i].y,Point[j].x,Point[j].y);
69             addedge(i,j,w);
70         }
71     printf("%.2f\n",Kruskal(m));
72 }

 

类似的有在上一篇文章中整理。

int func11(string str){
    int n = str.length();
    vector<vector<int> >dp(n,vector<int>(n));//初始化为0
    
    for(int i=n-1;i>=0;i--){
        dp[i][i] = 1;
        for(int j = i+1;j<n;j++){
            if(str[i]==str[j])
                dp[i][j] = dp[i+1][j-1]+2;
            else 
                dp[i][j] = max(dp[i+1][j],dp[i][j-1]);
                
        }
    }
    return dp[0][n-1];
}
int main() {
    string str;
    cin>>str;
    for(int i=0;i<str.length();i++){
        if(str[i]>='A'&&str[i]<='Z'){
            str[i]+=('a'-'A');
        }
    }
    cout<<func11(str);
}

 


posted @ 2019-03-04 10:56  顾本无缘  阅读(189)  评论(0编辑  收藏  举报