算法设计与分析实验考试

复制代码请务必修改防止查重!!!

温馨提示:增加空格或重新排版为无效修改!!

棋盘覆盖问题

#include <iostream>
#include<fstream>
#include <iomanip>
#define MAX 1025
using namespace std;
int board[MAX][MAX];
int tile=1;
void ChessBoard(int tr,int tc,int dr,int dc,int size)
{   if(size==1
) return;        //递归出口
    int t=tile++;            //取一个L型骨,其牌号为tile
    int s=size/2;            //分割棋盘
    //考虑左上角象限
    if(dr<tr+s&&dc<tc+s
)        //特殊方格在此象限中
      ChessBoard(tr,tc,dr,dc,s)
;
    else                //此象限中无特殊方格
    {    board[tr+s-1][tc+s-1]=t
;    //用t号L型骨牌覆盖右下角
        ChessBoard(tr,tc,tr+s-1,tc+s-1,s)
;    //将右下角作为特殊方格继续处理该象限
    }
    //考虑右上角象限
    if(dr<tr+s&&dc>=tc+s
)
       ChessBoard(tr,tc+s,dr,dc,s)
;        //特殊方格在此象限中
    else                    //此象限中无特殊方格
    {    board[tr+s-1][tc+s]=t
;        //用t号L型骨牌覆盖左下角
    ChessBoard(tr,tc+s,tr+s-1,tc+s,s)
;  //将左下角作为特殊方格继续处理该象限
    }
   //处理左下角象限
    if(dr>=tr+s&&dc<tc+s
)        //特殊方格在此象限中
       ChessBoard(tr+s,tc,dr,dc,s)
;
    else                //此象限中无特殊方格
    {   board[tr+s][tc+s-1]=t
;      //用t号L型骨牌覆盖右上角
        ChessBoard(tr+s,tc,tr+s,tc+s-1,s)
;    //将右上角作为特殊方格继续处理该象限
    }
    //处理右下角象限
    if(dr>=tr+s&&dc>=tc+s
)        //特殊方格在此象限中
        ChessBoard(tr+s,tc+s,dr,dc,s)
;
    else                //此象限中无特殊方格
    {    board[tr+s][tc+s]=t
;      //用t号L型骨牌覆盖左上角
       ChessBoard(tr+s,tc+s,tr+s,tc+s,s)
;      //将左上角作为特殊方格继续处理该象限
    }
}
int main()
{
int dr,dc,size;
int j,i;
cin>>size;
cin>>dr>>dc;
ChessBoard(0,0,dr,dc,size);
for(i=0;i<size;i++){
  cout<<left;
  for(j=0;j<size;j++)
  {
    cout<<setfill(' ')<<setw(5)<<board[i][j];
  }
  cout<<endl;
}
return 0;
}

快速排序

#include <iostream>

#define MAXSIZE 1000

using namespace std;

typedef struct

{

 int key;

 char *otherinfo;

}ElemType;

typedef struct

{

 ElemType *r;

 int  length;

}SqList;

int Partition(SqList &L,int low,int high)

{

  int pivotkey;

  L.r[0]=L.r[low];

  pivotkey=L.r[low].key;

  while(

low<high

)

  {

    while(

low<high&&L.r[high].key>=pivotkey

) --high;

    L.r[low]=L.r[high];

    while(

low<high&&L.r[low].key<=pivotkey

) ++low;

    L.r[high]=L.r[low];

  }

  L.r[low]=L.r[0];

  return  low;

}

void QSort(SqList &L,int low,int high)

{

  int pivotloc;

  if(low<high)

   {

    pivotloc= Partition(L,low,high)

;

    QSort(L,low,pivotloc-1)

;

    QSort(L,pivotloc+1,high)

;

   }

}

void QuickSort(SqList &L)

{

   QSort(L,1,L.length);

}

void Create_Sq(SqList &L)

{

 int i,n;

 cin>>n;    //输入的值不大于 MAXSIZE

 for(i=1;i<=n;i++)

 {

  cin>>L.r[i].key;

  L.length++;

 }

}

void show(SqList L)

{

 int i;

 for(i=1;i<=L.length;i++)

  if(i==1)

   cout<<L.r[i].key;

  else

   cout<<" "<<L.r[i].key;

}

int main()

{

 SqList L;

 L.r=new ElemType[MAXSIZE+1];

 L.length=0;

 Create_Sq(L);

 QuickSort(L);

 show(L);

 return 0;

}

归并排序

#include <iostream>

#define MAXSIZE 1000

using namespace std;

typedef struct

{

 int key;

 char *otherinfo;

}ElemType;

                    

typedef struct

{

 ElemType *r;

 int  length;

}SqList;

                                                                        

void Create_Sq(SqList &L)

{

 int i,n;

 cin>>n;    //输入的值不大于 MAXSIZE

 for(i=1;i<=n;i++)

 {

  cin>>L.r[i].key;

  L.length++;

 }

}

void show(SqList L)

{

 int i;

 for(i=1;i<=L.length;i++)

  if(i==1)

   cout<<L.r[i].key;

  else

   cout<<" "<<L.r[i].key;

}

void Merge(ElemType R[],ElemType T[],int low,int mid,int high)

{

 int i,j,k;

 i=low; j=mid+1;k=low;

 while(i<=mid&&j<=high)

 {                     

   if(R[i].key<=R[j].key) T[k++]=R[i++];

   else T[k++]=R[j++];

 }

 while(i<=mid)

   T[k++]=R[i++];                 

 while(j<=high)

   T[k++]=R[j++];                       

}

void MSort(ElemType R[],ElemType T[],int low,int high)

{

  int mid;

  ElemType *S=new ElemType[MAXSIZE];

  if(low==high)

    

T[low]=R[low]

;

  else

  {

    mid=(low+high)/2;

    

MSort(R,S,low,mid)

;

    

MSort(R,S,mid+1,high)

;

    

Merge(S,T,low,mid,high)

;

  }

}

void MergeSort(SqList &L)

{

   MSort(L.r,L.r,1,L.length);

}

int main()

{

  SqList R;

  R.r=new ElemType[MAXSIZE+1];

  R.length=0;

  Create_Sq(R);

  MergeSort(R);

  show(R);

  return 0;

}

部分背包问题(贪心法)

#include <stdio.h>

#include <string.h>

#include <iostream>

#include <algorithm>

using namespace std;

#define MAXN 51

//问题表示

int n;

double W;                    //限重

struct NodeType

{   int no;

    double w;

    double v;

    double p;                    //p=v/w

    float x;

    bool operator<(const NodeType &s) const

    {

        return p>s.p;            //按p递减排序

    }

};

NodeType A[MAXN]={{0}};    //下标0不用

//求解结果表示

double V;                        //最大价值

bool cmp(const NodeType &a,const NodeType &b)

{

    return a.no<b.no;

}

void Knap()                        //求解背包问题并返回总价值

{

    V=0;                        //V初始化为0

    double weight=W;            //背包中能装入的余下重量

    int i=1;

    while (

A[i].w<=weight

)    

    {    A[i].x=1;                    //装入物品i

        

weight-=A[i].w

;            

        V+=A[i].v;                //累计总价值

        

i++

;    

    }

    if (weight>0)                //当余下重量大于0

    {    A[i].x=

weight/A[i].w

;

        V+=A[i].x*A[i].v;            //累计总价值

    }

}

int main()

{   cin>>n>>W;

    for(int i=1;i<=n;i++)

    {

        cin>>A[i].no>>A[i].w>>A[i].v;A[i].x=0;

    }

    for (int i=1;i<=n;i++)            //求v/w

        A[i].p=A[i].v/A[i].w;

    sort(A+1,A+n+1);                //排序

    Knap();

    sort(A+1,A+n+1,cmp);

    for(int j=1;j<=n;j++)

        cout<<A[j].no<<" "<<A[j].x*A[j].v<<endl;

    cout<<V;

    return 0;

}

最小生成树(普里姆算法)

#include <iostream>

#define MVNum 100

#define MaxInt 32767

using namespace std;

struct edge{

    char adjvex;

    int lowcost;

}closedge[MVNum];

typedef struct{

    char vexs[MVNum];   

    int arcs[MVNum][MVNum];

    int vexnum,arcnum;

}AMGraph;

int LocateVex(AMGraph G , char v);//实现细节隐藏

int CreateUDN(AMGraph &G);//实现细节隐藏

int Min(AMGraph G){

    int i;

    int index = -1;

    int min = MaxInt;

    for(i = 0 ; i < G.vexnum ; ++i){

        if(

min > closedge[i].lowcost && closedge[i].lowcost != 0

){

            min = closedge[i].lowcost;

            index = i;

        }

    }

    return index;

}

void MiniSpanTree_Prim(AMGraph G, char u){

    int k , j , i;

    char u0 , v0;

    k =LocateVex(G, u);

    for(j = 0; j < G.vexnum; ++j){

        if(j != k){  

            closedge[j].adjvex =

u

;

            closedge[j].lowcost =

G.arcs[k][j]

;

        }

    }

    closedge[k].lowcost =

0

;

    for(i = 1; i < G.vexnum; ++i){

        k =

Min(G)

;  

        u0 = closedge[k].adjvex;

        v0 = G.vexs[k];

        cout << u0 << "->" << v0 << endl;

        closedge[k].lowcost =

0

;

        for(j = 0; j < G.vexnum; ++j)

            if(G.arcs[k][j] < closedge[j].lowcost){

                closedge[j].adjvex =

G.vexs[k]

;

                closedge[j].lowcost =

G.arcs[k][j]

;

            }

    }

}

int main(){

    AMGraph G;

    CreateUDN(G);

    char u;

    cin >> u;

    MiniSpanTree_Prim(G , u);

    return 0;

}

求解活动安排问题(贪心法)

#include <stdio.h>

#include <string.h>

#include <iostream>

#include <algorithm>

using namespace std;

#define MAX 51

//问题表示

struct Action

{    int b;                        //活动起始时间

    int e;                        //活动结束时间

    bool operator<(const Action &s) const    //重载<关系函数

    {

        return e<=s.e;            //用于按活动结束时间递增排序

    }

};

int n;

Action A[MAX];    

bool flag[MAX];                    //标记选择的活动

int Count=0;                    //选取的兼容活动个数

void solve()                    //求解最大兼容活动子集

{

    memset(flag,0,sizeof(flag));//初始化为false

    sort(A,A+n);            //A[1..n]按活动结束时间递增排序

    int preend=0;                //前一个兼容活动的结束时间

    for (int i=0;i<n;i++)

    {    if (

A[i].b>=preend

)

        {    

flag[i]=true

;        

            

preend=A[i].e

;

        }

    }

}

int main()

{    cin>>n;

    for (int i=0;i<n;i++)

       cin>>A[i].b>>A[i].e;

    solve();

    for (int i=0;i<n;i++)

        if (flag[i])

        {

            printf("[%d,%d]\n",A[i].b,A[i].e);

            Count++;

        }

    cout<<Count;

    return 0;

}

多段图问题(动态规划法)

#include<bits/stdc++.h>

using namespace std;

const int N = 20;

const int MAX = 1000;

int arc[N][N];

int Backpath(int n);

int creatGraph();

int main()

{

    int n = creatGraph( );

    int pathLen = Backpath(n);

    cout<<pathLen;

    return 0;

}

int creatGraph()

{

    int i, j, k;

    int weight;

    int vnum, arcnum;

    cin>>vnum>>arcnum;

    for (i = 0; i < vnum; i++)

        for (j = 0; j < vnum; j++)

            arc[i][j] = MAX;

    for (k = 0; k < arcnum; k++)

    {

        cin>>i>>j>>weight;

        arc[i][j] = weight;

    }

    return vnum;

}

int Backpath(int n)

{

    int i, j, temp;

    int cost[N];

    int path[N];

    for(i = 0; i < n; i++)

    {

        cost[i] = MAX;

        path[i] = -1;

    }

    cost[0] = 0;

    for(j = 1; j < n; j++)

    {

        for(i = j - 1; i >= 0; i--)

        {

            if (

arc[i][j] + cost[i] < cost[j]

)

            {

                

cost[j] = arc[i][j] + cost[i]

;

                

path[j]

 = i;

            }

        }

    }

    return

cost[n-1]

;

}

最短路径(弗洛伊德算法)

#include <iostream>

using namespace std;

#define MaxInt 32767

#define MVNum 100

typedef char VerTexType;

typedef int ArcType;

int Path[MVNum][MVNum];    

int D[MVNum][MVNum];

typedef struct{

    VerTexType vexs[MVNum];

    ArcType arcs[MVNum][MVNum];

    int vexnum,arcnum;

}AMGraph;

int LocateVex(AMGraph G , VerTexType v);//实现细节隐藏

void CreateUDN(AMGraph &G);//实现细节隐藏

void ShortestPath_Floyed(AMGraph G){

    int i , j , k ;

    for (i = 0; i < G.vexnum; ++i)

        for(j = 0; j < G.vexnum; ++j){

            D[i][j] =

G.arcs[i][j]

;

            if(D[i][j] < MaxInt && i != j)

Path[i][j]=i

;

            else Path [i][j] = -1;

        }

    for(k = 0; k < G.vexnum; ++k)

        for(i = 0; i < G.vexnum; ++i)

            for(j = 0; j < G.vexnum; ++j)

                if(

D[i][k] + D[k][j]

 < D[i][j]){

                    D[i][j] =

D[i][k]+D[k][j]

;

                    Path[i][j] =

Path[k][j]

;

                }

}

void DisplayPath(AMGraph G , int begin ,int temp ){

    if(Path[begin][temp] != -1){

        DisplayPath(G , begin ,Path[begin][temp]);

        cout << G.vexs[Path[begin][temp]] << "->";

    }

}

int main(){

    AMGraph G;

    char start , destination;

    int num_start , num_destination;

    CreateUDN(G);

    ShortestPath_Floyed(G);

    cin >> start >> destination;

    num_start = LocateVex(G , start);

    num_destination = LocateVex(G , destination);

    DisplayPath(G , num_start , num_destination);

    cout << G.vexs[num_destination]<<endl;

    cout << D[num_start][num_destination];

    return 0;

}

求解图的m着色问题(回溯法)

#include <stdio.h>

#include <string.h>

#define MAXN 20                //图最多的顶点个数

int n,k,m;

int a[MAXN][MAXN];

int count=0;                //全局变量,累计解个数

int x[MAXN];                //全局变量,x[i]表示顶点i的着色

bool Same(int i)            //判断顶点i是否与相邻顶点存在相同的着色

{

    for (int j=1;j<=n;j++)

        if (

a[i][j]==1 && x[i]==x[j]

)

            return false;

    return true;

}

void dfs(int i)                    //求解图的m着色问题

{

    if (i>n)                    

    {

        

count++

;            

    }

    else

    {

        for (int j=1;j<=m;j++)    

        {

            x[i]=j;

            if (

Same(i)

)        

                dfs(i+1);

            

x[i]=0

;            

        }

    }

}

int main()

{

    memset(a,0,sizeof(a));        //a初始化

    memset(x,0,sizeof(x));        //x初始化

    int x,y;

    scanf("%d%d%d",&n,&k,&m);    //输入n,k,m

    for (int j=1;j<=k;j++)

    {

        scanf("%d%d",&x,&y);    //输入一条边的两个顶点

        a[x][y]=1;                //无向图的边对称

        a[y][x]=1;

    }

    dfs(1);                        //从顶点1开始搜索

    if (count>0)                //输出结果

        printf("%d",count);

    else

        printf("-1");

    return 0;

}

0/1背包问题(回溯法)

#include <stdio.h>

#include <string.h>

#include <iostream>

#define MAXN 20                //最多物品数

using namespace std;

int n;                        //物品数

int W;                        //限制重量

int w[MAXN]={0};            //存放物品重量,不用下标0元素

int v[MAXN]={0};            //存放物品价值,不用下标0元素

int x[MAXN];                    //存放最终解

int maxv;                         //存放最优解的总价值

void dfs(int i,int tw,int tv,int rw,int op[]) //求解0/1背包问题

{

    int j;

    if (i>n)                    //找到一个叶子结点

    {    if (

tw==W && tv>maxv

)     //找到一个满足条件的更优解,保存它

        {    maxv=tv;

            for (

j=1;j<=n;j++

)    //复制最优解

                x[j]=op[j];

        }

    }

    else                        //尚未找完所有物品

    {    if (

tw+w[i]<=W

)          //左孩子结点剪枝:满足条件时才放入第i个物品

        {

            op[i]=1;            //选取第i个物品

            dfs(

i+1,tw+w[i],tv+v[i],rw-w[i],op

);

        }

        op[i]=0;                //不选取第i个物品,回溯

        if (

tw+rw>W

)            //右孩子结点剪枝

            dfs(

i+1,tw,tv,rw-w[i],op

);

    }

}

void dispasolution()            //输出最优解

{    int i;

    for (i=1;i<=n;i++)

        if (x[i]==1)

            printf("%d ",i);

    printf("\n%d %d",W,maxv);

}

int main()

{

    int i;

    cin>>n>>W; //输入物体个数及背包载重量

    for(int i=1;i<=n;i++)//输入各物体重量及价值

        cin>>w[i]>>v[i];

    int op[MAXN];                //存放临时解

    memset(op,0,sizeof(op));

    int rw=0;

    for (int i=1;i<=n;i++)

        rw+=w[i];

    dfs(1,0,0,rw,op);

    dispasolution();

    return 0;

}

求解n皇后问题(递归回溯法)

#include <stdio.h>

#include <stdlib.h>

#define N 20                    //最多皇后个数

int q[N];                        //存放各皇后所在的列号,即(i,q[i])为一个皇后位置

void dispasolution(int n)        //输出n皇后问题的一个解

{

    for (int i=1;i<=n;i++)

        printf("(%d,%d)",i,q[i]);

    printf("\n");

}

bool place(int i,int j)            //测试(i,j)位置能否摆放皇后

{

    if (i==1) return true;        //第一个皇后总是可以放置

    int k=1;

    while (k<i)            //k=1~i-1是已放置了皇后的行

    {    if ((q[k]==j) || (abs(q[k]-j)==abs(i-k)))

            

return false

;

        k++;

    }

    

return true

;

}

void queen(int i,int n)            //放置1~i的皇后

{    if (i>n)

        dispasolution(n);        //所有皇后放置结束

    else

    {

        for (int j=1;j<=n;j++)        //在第i行上试探每一个列j

            if (

place(i,j)

)            //在第i行上找到一个合适位置(i,j)

            {    q[i]=j;

                

queen(i+1,n)

;

            }

    }

}

int main()

{    int n;                    //n为存放实际皇后个数

    scanf("%d",&n);

    if (n<=20)

        queen(1,n);                //放置1~i的皇后

    return 0;

}

0/1背包问题(回溯法)
void dfs(int i,int tw,int tv,int rw,int op[]) {
    if(i > n) {
        if(tw == W && tv > maxv) {
            maxv = tv;
            for(int j = 1; j <= n; j ++ ) x[j] = op[j];
        }
    } else {
        if(tw + w[i] <= W) {
            op[i] = 1;
            dfs(i + 1, tw + w[i], tv + v[i], rw - w[i], op);
        }
        op[i] = 0;
        if(tw + rw > W) dfs(i + 1, tw, tv, rw - w[i], op);
    }
}

快速排序(分治法)
int Partition(SqList &L,int low,int high) {
    L.r[0] = L.r[low];
    int t = L.r[low].key;
    
    while(low < high) {
        while(low < high && L.r[high].key >= t) high --;
        L.r[low] = L.r[high];
        while(low < high && L.r[low].key <= t) low ++ ;
        L.r[high] = L.r[low];
    }
    L.r[low] = L.r[0];
    return low;
    
}

void QSort(SqList &L,int low,int high) {
    if(low < high) {
        int t = Partition(L, low, high);
        QSort(L, low, t - 1);
        QSort(L, t + 1, high);
    }
    
}

棋盘覆盖问题(分治法)
void ChessBoard(int tr,int tc,int dr,int dc,int size) {
    if(size == 1) return;
    
    int s = size / 2;
    int t = tile ++;
    
    if(dr < tr + s && dc < tc + s) ChessBoard(tr, tc, dr, dc, s);
    else {
        board[tr + s - 1][tc + s - 1] = t;
        ChessBoard(tr, tc, tr + s - 1, tc + s - 1, s);
    }
    
    if(dr < tr + s && dc >= tc + s) ChessBoard(tr, tc + s, dr, dc, s);
    else {
        board[tr + s - 1][tc + s] = t;
        ChessBoard(tr, tc + s, tr + s - 1, tc + s, s);
    }
    
    if(dr >= tr + s && dc < tc + s) ChessBoard(tr + s, tc, dr, dc, s);
    else {
        board[tr + s][tc + s - 1] = t;
        ChessBoard(tr + s, tc, tr + s, tc + s - 1, s);
    }
    
    if(dr >= tr + s && dc >= tc + s) ChessBoard(tr + s, tc + s, dr, dc, s);
    else {
        board[tr + s][tc + s] = t;
        ChessBoard(tr + s, tc + s, tr + s, tc + s, s);
    }
}

求解活动安排问题(贪心法)
void solve() {
    sort(A, A + n);
    int t = 0;
    for(int i = 0; i < n; i ++ ) {
        if(A[i].b >= t) {
            flag[i] = true;
            t = A[i].e;
        }
    }
}

最小生成树(克鲁斯卡尔算法)
int p[MVNum];

int find(int x) {
    if(p[x] != x) p[x] = find(p[x]);
    return p[x];
}

void Kruskal(AMGraph G) {
    for(int i = 0; i < G.vexnum; i ++ ) p[i] = i;
    
    for(int k = 0; k < G.arcnum; k ++ ) {
        int min = MaxInt, mini = MaxInt, minj = MaxInt;
        for(int i = 0; i < G.vexnum; i ++ ) {
            for(int j = 0; j < G.vexnum; j ++ ) {
                if(G.arcs[i][j] < min) {
                    min = G.arcs[i][j];
                    mini = i;
                    minj = j;
                }
            }
        }
        int pa = find(mini), pb = find(minj);
        if(pa != pb) {
            p[pa] = pb;
            printf("%d->%d\n", mini, minj);
        }
        G.arcs[mini][minj] = G.arcs[minj][mini] = MaxInt;
    }
}

求解最长递增子序列问题(动态规划法)
void IncreaseOrder(int a[],int dp[],int x[][N],int n) {
    for(int i = 0; i < n; i ++ ) {
        dp[i] = 1;
        x[i][0] = a[i];
        
        int max = 1, maxi = i;
        for(int j = 0; j < i; j ++ ) {
            if(a[j] < a[i] && dp[j] + 1 > max) {
                max = dp[j] + 1;
                maxi = j;
            }
        }
        
        if(maxi != i) {
            dp[i] = max;
            for(int j = 0; j < max - 1; j ++ ) x[i][j] = x[maxi][j];
            x[i][max - 1] = a[i];
        }
    }
}

最短路径(弗洛伊德算法)
void ShortestPath_Floyed(AMGraph G){ 
    int i , j , k ;
    for (i = 0; i < G.vexnum; ++i)
        for(j = 0; j < G.vexnum; ++j){ 
            D[i][j] = G.arcs[i][j];
            if(D[i][j] < MaxInt && i != j) Path[i][j] = i;
            else Path [i][j] = -1; 
        }
    for(k = 0; k < G.vexnum; ++k) 
        for(i = 0; i < G.vexnum; ++i) 
            for(j = 0; j < G.vexnum; ++j)
                if(D[i][k] + D[k][j] < D[i][j]) {
                    D[i][j] = D[i][k] + D[k][j];
                    Path[i][j] = Path[k][j];
                }


}

求解图的m着色问题(回溯法)
void dfs(int i) {
    if(i > n) count ++;
    else {
        for(int j = 1; j <= m; j ++ ) {
            x[i] = j;
            if(Same(i)) dfs(i + 1);
            x[i] = 0;
        }
    }
}

7-1 快速排序
#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;

const int N = 1e5 + 10;

int n;
int a[N];

int main(){
    
    cin >> n;
    for(int i = 0; i < n; i ++ ) cin >> a[i];
    
    sort(a, a + n);
    
    for(int i = 0; i < n; i ++ ) {
        if(i == 0) cout << a[i];
        else cout << " " << a[i];
    }
    
    
    return 0;
}

7-2 棋盘覆盖问题
#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;

const int N = 1050;

int tile = 1;
int dr, dc, len;
int g[N][N];

void chessBorad(int tr, int tc, int dr, int dc, int len) {
    if(len == 1) return;
    
    int t = tile ++;
    int s = len / 2;
    
    if(dr < tr + s && dc < tc + s) chessBorad(tr, tc, dr, dc, s);
    else {
        g[tr + s - 1][tc + s - 1] = t;
        chessBorad(tr, tc, tr + s - 1, tc + s - 1, s);
    }
    
    if(dr < tr + s && dc >= tc + s) chessBorad(tr, tc + s, dr, dc, s);
    else {
        g[tr + s - 1][tc + s] = t;
        chessBorad(tr, tc + s, tr + s - 1, tc + s, s);
    }
    
    if(dr >= tr + s && dc < tc + s) chessBorad(tr + s, tc, dr, dc, s);
    else {
        g[tr + s][tc + s - 1] = t;
        chessBorad(tr + s, tc, tr + s, tc + s - 1, s);
    }
    
    if(dr >= tr + s && dc >= tc + s) chessBorad(tr + s, tc + s, dr, dc, s);
    else {
        g[tr + s][tc + s] = t;
        chessBorad(tr + s, tc + s, tr + s, tc + s, s);
    }
}

int main(){
    
    cin >> len >> dr >> dc;
    chessBorad(0, 0, dr, dc, len);
    
    for(int i = 0; i < len; i ++ ) {
        for(int j = 0; j < len; j ++ ) {
            printf("%-5d", g[i][j]);
        }
        cout << endl;
    }
    
    
    return 0;
}

7-3 活动选择问题
#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;

const int N = 1e5 + 10;

struct T {
    int l, r;
}t[N];

int n, cnt, now;

bool cmp(struct T a, struct T b) {
    return a.r < b.r;
}

int main(){
    
    cin >> n;
    for(int i = 0; i < n; i ++ ) cin >> t[i].l >> t[i].r;
    
    sort(t, t + n, cmp);
    
    for(int i = 0; i < n; i ++ ) {
        if(t[i].l >= now) {
            cnt ++;
            now = t[i].r;
        }
    }
    
    cout << cnt;
    
    
    return 0;
}

7-4 最小生成树-kruskal
#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;

const int N = 1e7 + 10;

struct e {
    int a, b, c;
}e[N];

int n, m, cnt;
int ans;
int p[N];

int find(int x) {
    if(p[x] != x) p[x] = find(p[x]);
    return p[x];
}

bool cmp(struct e a, struct e b) {
    return a.c < b.c;
}

int main() {

    cin >> n >> m;
    for(int i = 0; i < m; i ++ ) scanf("%d %d %d", &e[i].a, &e[i].b, &e[i].c);
    
    sort(e, e + m, cmp);
    
    for(int i = 0; i < n; i ++ ) p[i] = i;
    
    for(int i = 0; i < m; i ++ ) {
        int pa = find(e[i].a);
        int pb = find(e[i].b);
        if(pa != pb) {
            p[pa] = pb;
            ans += e[i].c;
            cnt ++;
        }
        if(cnt == n - 1) break;
    }
    
    cout << ans;
       
    return 0;
}

7-5 最长公共子序列长度
#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;

const int N = 1010;

int n, m;
char a[N], b[N];
int f[N][N];

int main(){
    
    scanf("%s %s", a + 1, b + 1); 
    n = strlen(a + 1);
    m = strlen(b + 1);
    
    for(int i = 1; i <= n; i ++ ) {
        for(int j = 1; j <= m; j ++ ) {
            f[i][j] = max(f[i - 1][j], f[i][j - 1]);
            if(a[i] == b[j]) f[i][j] = max(f[i][j], f[i - 1][j - 1] + 1);
        }
    }
    
    cout << f[n][m];
    
    return 0;
}

7-6 最短路径之Floyd
#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;

const int N = 110;
const int INF = 0x3f3f3f3f;

int n, m;
int d[N][N];
string p[N][N];

void floyd() {
    
    for(int k = 0; k < n; k ++ ) {
        for(int i = 0; i < n; i ++ ) {
            for(int j = 0; j < n; j ++ ) {
                if(d[i][k] + d[k][j] < d[i][j]) {
                    d[i][j] = d[i][k] + d[k][j];
                    p[i][j] = p[i][k] + p[k][j];
                }
            }
        }
    }
}

void print(int a, int b) {
    if(d[a][b] > INF / 2) printf("%d->%d:-1\n", a, b);
    else {
        string s = p[a][b];
        string str = "";
        str += s[0];
        for(int i = 1; i < s.size(); i ++ ) {
            if(s[i] != s[i - 1]) str += s[i];
        }
        cout << str << ":" << d[a][b] << endl;
    }
}

int main(){
    
    cin >> n >> m;
    
    for(int i = 0; i < n; i ++ ) {
        for(int j = 0; j < n; j ++ ) {
            if(i == j){
                d[i][j] = 0;
                p[i][j] = to_string(i) + "->" + to_string(j);
            }
            else d[i][j] = INF;
        }
    }
    
    for(int i = 0; i < m; i ++ ) {
        int a, b, c;
        cin >> a >> b >> c;
        d[a][b] = c;
        p[a][b] = to_string(a) + "->" + to_string(b);
    }
    
    floyd();
    
    for(int i = 0; i < 2; i ++ ) {
        int a, b;
        cin >> a >> b;
        print(a, b);
    }
    
    int maxi = -1, maxj = -1, maxx = -INF;
    for(int i = 0; i < n; i ++ ) {
        for(int j = 0; j < n; j ++ ) {
            if(d[i][j] > maxx && d[i][j] < INF / 2) {
                maxi = i;
                maxj = j;
                maxx = d[i][j];
            }
        }
    }
    
    print(maxi, maxj);
    
    
    return 0;
}

7-7 图着色问题
#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;

const int N = 510;

int n, m, k;
int p, sum;
int color[N];
int cnt[N];
struct E {
    int l, r;
}e[N * N];

int main(){
    
    cin >> n >> m >> k;
    for(int i = 0; i < m; i ++ ) cin >> e[i].l >> e[i].r;
    
    cin >> p;
    while(p -- ) {
        memset(cnt, 0, sizeof cnt);
        bool flag = true;
        sum = 0;
        
        for(int i = 1; i <= n; i ++ ) {
            cin >> color[i];
            if(cnt[color[i]] == 0) {
                cnt[color[i]] ++;
                sum ++;
            }
        }
        
        if(sum != k) flag = false;
        
        for(int i = 0; i < m; i ++ ) {
            if(color[e[i].l] == color[e[i].r]) {
                flag = false;
                break;
            }
        }
        
        if(flag) cout << "Yes" << endl;
        else cout << "No" << endl;
    }
    
    return 0;
}

7-8 0/1背包问题
#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;

const int N = 1010;

int n, M;
int p[N];
int w[N], v[N];
int f[N][N];

int main(){
    
    cin >> n >> M;
    for(int i = 1; i <= n; i ++ ) cin >> w[i] >> v[i];
    
    for(int i = 1; i <= n; i ++ ) {
        for(int j = 1; j <= M; j ++ ) {
            f[i][j] = f[i - 1][j];
            if(j >= w[i]) f[i][j] = max(f[i][j], f[i - 1][j - w[i]] + v[i]);
        }
    }
    
    int k = 0;
    for(int i = n, j = M; f[i][j] > 0 && i > 0; i -- ) {
        if(f[i][j] != f[i - 1][j]) {
            p[k ++] = i;
            j -= w[i];
        }
    }
    
    if(f[n][M] == 0) {
        cout << "No" << endl << "0";
    } else {
        for(int i = k - 1; i >= 0; i -- ) cout << p[i] << " " ;
        cout << endl << f[n][M];
    }
    
    
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值