算法设计与分析考前复习

算法设计与分析考前复习

qiwang的NOJ系统在考前一天崩了,强烈建议开发新OJ
另外,由于以下这些题是我上完数电实验用了下午和晚上时间写的,可能会出一些错。

分治法复习

二分查找

描述

给定一个单调递增的整数序列,问某个整数是否在序列中。

输入

第一行为一个整数n,表示序列中整数的个数;第二行为n(n不超过10000)个整数;第三行为一个整数m(m不超过50000),表示查询的个数;接下来m行每行一个整数k。

输出

每个查询的输出占一行,如果k在序列中,输出Yes,否则输出No。

输入样例

5
1 3 4 7 11
3
3
6
9

输出样例

Yes
No
No

#include <iostream>
using namespace std;
bool BinarySearch(int *a,int low,int high,int k)
{
    int mid;
    if(low <= high)
    {
        mid = (low + high) / 2;
        if(a[mid] == k)
            return true;
        if(a[mid] > k)
            return BinarySearch(a, low, mid - 1, k);
        else
            return BinarySearch(a, mid + 1, high, k);
    }
    else
        return false;
}
int main()
{
    int n1, n2, i;
    int a[10000], k[50000];
    cin >> n1;
    for (i = 0; i < n1;i++)
    {
        cin >> a[i];
    }
    cin >> n2;
    for (i = 0; i < n2;i++)
    {
        cin >> k[i];
    }
    for (i = 0; i < n2;i++)
    {
        if(BinarySearch(a,0,n1-1,k[i]))
            cout << "Yes" << endl;
        else
            cout << "No" << endl;
    }
}

快速排序

描述

给定一个数列,用快速排序算法把它排成升序。

输入

第一行是一个整数n(n不大于10000),表示要排序的数的个数;下面一行是用空格隔开的n个整数。

输出

输出排序后的数列,每个数字占一行。

输入样例

5
3 2 1 4 5

输出样例

1
2
3
4
5

#include <iostream>
using namespace std;
void QuickSort(int *a,int low,int high)
{
    int i = low, j = high;
    int temp = a[low];
    while(i != j)
    {
        while(a[j] >= temp && j > i)
            j--;
        a[i] = a[j];
        while(a[i] <= temp && j > i)
            i++;
        a[j] = a[i];
    }
    a[i] = temp;
    if(i > low)
        QuickSort(a, low, i);
    if(i < high)
        QuickSort(a, i + 1, high);
}
int main()
{
    int i, n;
    int a[10000];
    cin >> n;
    for (i = 0; i < n;i++)
    {
        cin >> a[i];
    }
    QuickSort(a, 0, n - 1);
    for (i = 0; i < n;i++)
    {
        cout << a[i] << endl;
    }
}

循环赛日程表

#include <iostream>
#define MAX 100
using namespace std;
int k;
int a[MAX][MAX];
void Plan(int k)
{
    int i, j, n, t, temp;
    n = 2;
    a[1][1] = 1;
    a[1][2] = 2;
    a[2][1] = 2;
    a[2][2] = 1;
    for (t = 1; t < k;t++)
    {
        temp = n;
        n = n * 2;
        for (i = temp + 1; i <= n;i++)
            for (j = 1; j <= temp;j++)
                a[i][j] = a[i - temp][j] + temp;
        for (i = 1; i <= temp;i++)
            for (j = temp + 1; j <= n; j++)
                a[i][j] = a[i + temp][(j + temp) % n];
        for (i = temp + 1; i <= n;i++)
            for (j = temp + 1; j <= n;j++)
                a[i][j] = a[i - temp][j - temp];
    }
}
int main()
{
    k = 3;
    int n = 1 << k;
    Plan(k);
    for (int i = 1; i <= n;i++)
    {
        for (int j = 1; j <= n;j++)
        {
            cout << a[i][j] << " ";
        }
        cout << endl;
    }
}

回溯法复习

穷举n位二进制数

描述

输入一个小于20的正整数n,要求按从小到大的顺序输出所有的n位二进制数,每个数占一行。

输入

输入一个小于20的正整数n。

输出

按从小到大的顺序输出所有的n位二进制数,每个数占一行。

输入样例

3

输出样例

000
001
010
011
100
101
110
111

#include <iostream>
using namespace std;
int a[20];
int n;
void display()
{
    int i;
    for (i = 0; i < n;i++)
    {
        cout << a[i];
    }
    cout << endl;
}
void dfs(int i)
{
    int j;
    if(i == n)
    {
        display();
    }
    else{
        for (j = 0; j <= 1;j++)
        {
            a[i] = j;
            dfs(i + 1);
            a[i] = 0;
        }
    }
}
int main()
{
    cin >> n;
    dfs(0);
}

走迷宫

#include <iostream>
using namespace std;
int m, n;
int flag;
int maze[100][100];
bool check(int x,int y)
{
    if(maze[x][y] == 0 && x >= 0 && x < m && y >= 0 && y < n)
    {
        return true;
    }
    else
        return false;
}
void dfs(int start_x,int start_y,int end_x,int end_y)
{
    if(start_x == end_x && start_y == end_y)
    {
        flag = 1;
        return;
    }
    else{
        maze[start_x][start_y] = 1;
        if(check(start_x+1,start_y))
            dfs(start_x + 1, start_y, end_x, end_y);
        if(check(start_x,start_y+1))
            dfs(start_x, start_y + 1, end_x, end_y);
        if(check(start_x-1,start_y))
            dfs(start_x - 1, start_y, end_x, end_y);
        if(check(start_x,start_y-1))
            dfs(start_x, start_y - 1, end_x, end_y);
    }
}
int main()
{
    int i, j;
    int start_x, start_y;
    int end_x, end_y;
    cin >> m >> n;
    cin >> start_x >> start_y;
    cin >> end_x >> end_y;
    for (i = 0; i < m;i++)
    {
        for (j = 0; j < n;j++)
        {
            cin >> maze[i][j];
        }
    }
    dfs(start_x, start_y, end_x, end_y);
    if(flag)
        cout << "Yes" << endl;
    else
        cout << "No" << endl;
}

8皇后问题

描述

输出8皇后问题所有结果。

输入

没有输入。

输出

每个结果第一行是No n:的形式,n表示输出的是第几个结果;下面8行,每行8个字符,‘A’表示皇后,‘.’表示空格。不同的结果中,先输出第一个皇后位置靠前的结果;第一个皇后位置相同,先输出第二个皇后位置靠前的结果;依次类推。

输入样例

输出样例

输出的前几行:
No 1:
A…
…A…
…A
…A…
…A…
…A.
.A…
…A…
No 2:
A…
…A…
…A
…A…
…A.
…A…
.A…
…A…

#include <iostream>
#include <cmath>
int a[9];
int cnt;
using namespace std;
bool check(int x,int y)
{
    int i;
    for (i = 1; i < x;i++)
    {
        if(a[i] == y || abs(i - x) == abs(a[i] - y))
            return false;
    }
        return true;
}
void display()
{
    int i, j;
    for (i = 1; i <= 8;i++)
    {
        for (j = 1; j <= 8;j++)
        {
            if(a[i] == j)
                cout << 'A';
            else
                cout << '.';
        }
        cout << endl;
    }
}
void dfs(int i)
{
    if(i == 9)
    {
        cnt++;
        cout << "No " << cnt + 1 << ":" << endl;
        display();
    }
    else{
        int j;
        for (j = 1; j <= 8;j++)
        {
            if(check(i,j))
            {
                a[i] = j;
                dfs(i + 1);
                a[i] = 0;
            }
        }
    }
}
int main()
{
    dfs(1);
    cout << cnt;
}

堡垒问题

描述

城堡是一个4×4的方格,为了保卫城堡,现需要在某些格子里修建一些堡垒。城堡中的某些格子是墙,其余格子都是空格,堡垒只能建在空格里,每个堡垒都可以向上下左右四个方向射击,如果两个堡垒在同一行或同一列,且中间没有墙相隔,则两个堡垒都会把对方打掉。问对于给定的一种状态,最多能够修建几个堡垒。

输入

每个测例以一个整数n(1<=n<=4)开始,表示城堡的大小。接下来是n行字符每行n个,‘X’表示该位置是墙,‘.’表示该位置是空格。n等于0标志输入结束。

输出

每个测例在单独的一行输出一个整数:最多修建堡垒的个数。

输入样例

4
.X…

XX…

2
XX
.X
3
.X.
X.X
.X.
3

.XX
.XX
4




0

输出样例

5
1
5
2
4

#include <iostream>
using namespace std;
#define MAX 4
int n;
char maze[MAX][MAX];
int cnt;
int mmax;
bool collide(int row ,int col)
{
    int i;
    for (i = col; i >= 0;i--)
    {
        if(maze[row][i] == 'T')
            return false;
        if(maze[row][i] == 'X')
            break;
    }
    for (i = row; i >= 0;i--)
    {
        if(maze[i][col] == 'T')
            return false;
        if(maze[i][col] == 'X')
            break;
    }
    if(maze[row][col] == 'X')
        return false;
    return true;
}
void dfs(int i)
{
    int row = i / n;
    int col = i % n;
    int j, k;
    if(i == n * n)
    {
        int num = 0;
        for (j = 0; j < n;j++)
        {
            for (k = 0; k < n;k++)
            {
                if(maze[j][k] == 'T')
                    num++;
            }
        }
        if(num > mmax)
        {
            mmax = num;
        }
    }
    else{
        dfs(i + 1);
        if(collide(row,col))
        {
            maze[row][col] = 'T';
            dfs(i + 1);
            maze[row][col] = '.';
        }
    }
}
int main()
{
    int m[100];
    while(cin>>n,n)
    {
        int i, j;
        for (i = 0; i < n;i++)
        {
            for (j = 0; j < n;j++)
            {
                cin >> maze[i][j];
            }
        }
        dfs(0);
        m[cnt] = mmax;
        mmax = 0;
        cnt++;
    }
    int i;
    for (i = 0; i < cnt;i++)
    {
        cout << m[i] << endl;
    }
}

素数环问题

描述

把1到20这重新排列,使得排列后的序列A满足:
a. 任意相邻两个数之和是素数
b. 不存在满足条件a的序列B使得:A和B的前k(0 <= k <= 19)项相同且B的第k+1项比A的第k+1项小。(即按字典序排列的第一项)

输入

没有输入。

输出

输出A,两个数字之间用一个空格隔开,第一个数字前面和最后一个数字后面没有空格。

#include <iostream>
#include <cmath>
using namespace std;
int vis[21];
int a[21];
bool isprime(int num)
{
    int i;
    for (i = 2; i <= sqrt(num);i++)
    {
        if(num % i == 0)
            return false;
    }
    return true;
}
bool check(int place,int num)
{
    if(isprime(a[place - 1] + num) && !vis[num])
        return true;
    return false;
}
void display()
{
    int i;
    for (i = 1; i <= 20;i++)
    {
        cout << a[i] << " ";
    }
    cout << endl;
}
void dfs(int i)
{
    if(i == 21)
    {
        if(isprime(a[1]+a[20]))
        {
            display();
            exit(0);
        }
    }
    else{
        int j;
        for (j = 1; j <= 20;j++)
        {
            if(check(i,j))
            {
                vis[j] = 1;
                a[i] = j;
                dfs(i + 1);
                a[i] = 0;
                vis[j] = 0;
            }
        }
    }
}
int main()
{
    dfs(1);
}

分支限界法复习

加1乘2平方

描述

最简单的队列的使用
#include
#include
using namespace std;

queue q1;
int main()
{
int temp, x;
q1.push(5);//入队
q1.push(8);//入队
temp = q1.front();//访问队首元素
q1.pop();//出队
q1.empty();//判队列是否为空
q1.back();//返回队尾元素
q1.size();//返回队列长度
}

给定两个正整数m、n,问只能做加1、乘2和平方这三种变化,从m变化到n最少需要几次

输入

输入两个10000以内的正整数m和n,且m小于n

输出

输出从m变化到n的最少次数

输入样例

1 16

输出样例

3

#include <iostream>
#include <queue>
using namespace std;
int vis[10001];
int step[10001];
int m, n;
bool check(int num)
{
    if(vis[num] ||num > n)
        return false;
    return true;
}
int make_new_place(int root,int type)
{
    switch (type)
    {
    case 0:
        return root + 1;
    case 1:
        return root * 2;
    case 2:
        return root * root;
    }
    return 0;
}
void bfs(queue<int> q)
{
    q.push(m);
    while(!q.empty())
    {
        int pop_num = q.front();
        q.pop();
        int i;
        int new_num[3];
        for (i = 0; i < 3;i++)
        {
            new_num[i] = make_new_place(pop_num, i);
            if(check(new_num[i]))
            {
                q.push(new_num[i]);
                vis[new_num[i]] = pop_num;
                step[new_num[i]] = step[pop_num] + 1;
                if(new_num[i] == n)
                    return;
            }
        }
    }
}
int main()
{
    cin >> m >> n;
    queue<int> q;
    bfs(q);
    cout << step[n] << endl;
}

电子老鼠闯迷宫

描述

有一只电子老鼠被困在如下图所示的迷宫中。这是一个12*12单元的正方形迷宫,黑色部分表示建筑物,白色部分是路。电子老鼠可以在路上向上、下、左、右行走,每一步走一个格子。现给定一个起点S和一个终点T,求出电子老鼠最少要几步从起点走到终点。

输入

本题包含一个测例。在测例的第一行有四个由空格分隔的整数,分别表示起点的坐标S(x.y)和终点的坐标T(x,y)。从第二行开始的12行中,每行有12个字符,描述迷宫的情况,其中’X’表示建筑物,’.'表示路.

输出

输出一个整数,即电子老鼠走出迷宫至少需要的步数。

输入样例

2 9 11 8
XXXXXXXXXXXX
X…X.XXX
X.X.XX…X
X.X.XX.XXX.X
X.X…X…X
X.XXXXXXXXXX
X…X.X…X
X.XXX…XXXX
X…X…X
XXX.XXXX.X.X
XXXXXXX…XXX
XXXXXXXXXXXX

输出样例

28

#include <iostream>
#include <queue>
using namespace std;
int walk[4][2] = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}};
int maze[12][12];
int step[12 * 12];
int start_x, start_y, end_x, end_y;
void input()
{
    cin >> start_x >> start_y;
    cin >> end_x >> end_y;
    start_x--;
    start_y--;
    end_x--;
    end_y--;
    int i, j;
    char c;
    for (i = 0; i < 12;i++)
    {
        for (j = 0; j < 12;j++)
        {
            cin >> c;
            if(c == 'X')
                maze[i][j] = 1;
        }
    }
}
int make_new_place(int row,int col,int type)
{
    row += walk[type][0];
    col += walk[type][1];
    if(row >= 0 && row < 12 && col >= 0 && col <12 && maze[row][col] == 0)
    {
        return row * 12 + col;
    }
    return -1;
}
void bfs(queue<int>q)
{
    q.push(start_x * 12 + start_y);
    while(!q.empty())
    {
        int pop_num = q.front();
        q.pop();
        int place_r = pop_num / 12;
        int place_c = pop_num % 12;
        int new_num;
        int i;
        for (i = 0; i < 4;i++)
        {
            new_num = make_new_place(place_r, place_c, i);
            if(new_num != -1)
            {
                int row = new_num / 12;
                int col = new_num % 12;
                maze[row][col] = pop_num;
                step[new_num] = step[pop_num] + 1;
                q.push(new_num);
                if(row == end_x && col == end_y)
                {
                    return;
                }
            }
        }
    }
}
int main()
{
    input();
    queue<int> q;
    bfs(q);
    cout << step[end_x * 12 + end_y] << endl;
}

动态规划复习

最长公共子序列

时限:1000ms 内存限制:200000K 总时限:3000ms

描述

一个给定序列的子序列是在该序列中删去若干元素后得到的序列。确切地说,若给定序列X=<x1, x2,…, xm>,则另一序列Z=<z1, z2,…, zk>是X的子序列是指存在一个严格递增的下标序列 <i1, i2,…, ik>,使得对于所有j=1,2,…,k有:

Xij = Zj

如果一个序列S即是A的子序列又是B的子序列,则称S是A、B的公共子序列。
求A、B所有公共子序列中最长的序列的长度。

输入

输入共两行,每行一个由字母和数字组成的字符串,代表序列A、B。A、B的长度不超过200个字符。

输出

一个整数,表示最长各个子序列的长度。
格式:printf("%d\n");

输入样例

programming
contest

输出样例

2

#include <iostream>
#include <string>
#define max(a,b) ((a)>(b)?(a):(b))
using namespace std;
string a, b;
int dp[100][100];
void solve()
{
    int m = a.length();
    int n = b.length();
    int i, j;
    for (i = 1; i <= m;i++)
    {
        for (j = 1; j <= n;j++)
        {
            if(a[i-1] == b[j-1])
            {
                dp[i][j] = dp[i - 1][j - 1] + 1;
            }
            else{
                dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]);
            }
        }
    }
}
int main()
{
    cin >> a;
    cin >> b;
    solve();
    cout << dp[a.length()][b.length()] << endl;
}

矩阵连乘

时限:1000ms 内存限制:10000K 总时限:3000ms

描述

在科学计算中经常要计算矩阵的乘积。矩阵A和B可乘的条件是矩阵A的列数等于矩阵B的行数。若A是一个p×q的矩阵,B是一个q×r的矩阵,则其乘积C=AB是一个p×r的矩阵。计算C=AB总共需要p×q×r次乘法。
现在的问题是,给定n个矩阵{A1,A2,…,An}。其中Ai与Ai+1是可乘的,i=1,2,…,n-1。
要求计算出这n个矩阵的连乘积A1A2…An最少需要多少次乘法。

输入

输入数据的第一行是一个整树n(0 < n <= 10),表示矩阵的个数。
接下来的n行每行两个整数p,q( 0 < p,q < 100),分别表示一个矩阵的行数和列数。

输出

输出一个整数:计算连乘积最少需要乘法的次数。

输入样例

10
1 2
2 3
3 4
4 5
5 6
6 7
7 8
8 9
9 10
10 11

输出样例

438

#include <iostream>
#define MAX 1000000
using namespace std;
int N;
int p[101];
int dp[100][100];
void solve(int *p)
{
    int i, j, k, t, temp;
    for (i = 0; i <= N;i++)
    {
        dp[i][i] = 0;
    }
    for (t = 2; t <= N;t++)
    {
        for (i = 1; i <= N - t + 1; i++)
        {
            j = i + t - 1;
            dp[i][j] = MAX;
            for (k = i; k < j;k++)
            {
                temp = dp[i][k] + dp[k + 1][j] + p[i - 1] * p[k] * p[j];
                if(temp < dp[i][j])
                {
                    dp[i][j] = temp;
                }
            }
        }
    }
}
int main()
{
    int i;
    cin >> N;
    for (i = 0; i < N;i++)
    {
        cin >> p[i] >> p[i + 1];
    }
    solve(p);
    cout << dp[1][N] << endl;
}

防卫导弹

描述

一种新型的防卫导弹可截击多个攻击导弹。它可以向前飞行,也可以用很快的速度向下飞行,可以毫无损伤地截击进攻导弹,但不可以向后或向上飞行。但有一个缺点,尽管它发射时可以达到任意高度,但它只能截击比它上次截击导弹时所处高度低或者高度相同的导弹。现对这种新型防卫导弹进行测试,在每一次测试中,发射一系列的测试导弹(这些导弹发射的间隔时间固定,飞行速度相同),该防卫导弹所能获得的信息包括各进攻导弹的高度,以及它们发射次序。现要求编一程序,求在每次测试中,该防卫导弹最多能截击的进攻导弹数量,一个导弹能被截击应满足下列两个条件之一:
a)它是该次测试中第一个被防卫导弹截击的导弹;
b)它是在上一次被截击导弹的发射后发射,且高度不大于上一次被截击导弹的高度的导弹。

输入

多个测例。
每个测例第一行是一个整数n(n不超过100),第二行n个整数表示导弹的高度(数字的顺序即发射的顺序)。
n=0表示输入结束。

输出

每个测例在单独的一行内输出截击导弹的最大数目。

输入样例

5
5 6 100 6 61
0

输出样例

2

#include <iostream>
#include <cstring>
#define max(a,b) (((a)>(b))?(a):(b))
using namespace std;
int mmax;
int n;
int dp[100];
void solve(int *a)
{
    int i, j;
    for (i = 0; i < n;i++)
    {
        dp[i] = 1;
        for (j = 0; j < i;j++)
        {
            if(a[i] <= a[j])
            {
                dp[i] = max(dp[i], dp[j] + 1);
            }
        }
    }
    for (i = 0; i < n;i++)
        mmax = max(mmax, dp[i]);
}
int main()
{
    int i;
    int a[100];
    while(cin>>n,n)
    {
        for (i = 0; i < n;i++)
        {
            cin >> a[i];
        }
        solve(a);
        cout << mmax << endl;
        mmax = 0;
        memset(a, 0, sizeof(a));
        memset(dp, 0, sizeof(dp));
    }
}

最大连续子序列和问题

时限:1000ms 内存限制:10000K 总时限:3000ms

描述

给定一整数序列A0,A1, A2,… An-1 (可能有负数),求A0An-1的一个连续子序列AiAj,使得Ai到Aj的和最大。

输入

先输入一个正整数n(1<n<1000),再输入n个整数。

输出

输出最大连续子序列的和。

输入样例

10
2 -1 5 -7 2 -1 4 -2 4 -5

输出样例

7

#include <iostream>
#define max(a,b) ((a>b)?(a):(b))
using namespace std;
int mmax;
int dp[1000];
int n;
void solve(int *a)
{
    int i;
    if(a[0] >= 0)
        dp[0] = a[0];
    else
        dp[0] = 0;
    for (i = 1; i < n;i++)
    {
        dp[i] = max(a[i], dp[i - 1] + a[i]);
        if(dp[i] > mmax)
        {
            mmax = dp[i];
        }
    }
}
int main()
{
    cin >> n;
    int i;
    int a[1000];
    for (i = 0; i < n;i++)
    {
        cin >> a[i];
    }
    solve(a);
    cout << mmax << endl;
}

贪心法复习

活动安排

描述

Jack是一名nwpu的大一新生,对学校举办的各种活动都十分的好奇,想尽可能多的参加这些活动。Npwu每天共有N项活动,其开始结束时间分别为B[i],E[i],(i = 1,2,……N)
请问Jack一天最多能参加几项活动。当然,Jack在同一时间内只能参加一项活动,即jack参加的活动时间上不能重叠,但时间为[t1,t2],[t2,t3]的两个活动是可以同时参加的。

输入

第一行 一个整数N(1<=n<=1000)表示活动总数。
接下来N行表示各活动的起始,结束时间0<=B[i]<E[i]<24

输出

一个整数表示Jack最多能参加的活动数目。

输入样例

4
10 11
2 3
8 10
0 2

输出样例

4

#include <iostream>
#include <algorithm>
using namespace std;
struct Action{
    int begin;
    int end;
};
Action A[100];
int n;
int cnt;
bool cmp(Action s1,Action s2)
{
    if(s1.end == s2.end)
    {
        return s1.begin <= s2.begin;
    }
    else{
        return s1.end < s2.end;
    }
}
void solve()
{
    sort(A + 1, A + n + 1, cmp);
    int i;
    int preend = 0;
    for (i = 1; i <= n;i++)
    {
        if(preend <= A[i].begin)
        {
            preend = A[i].end;
            cnt++;
        }
    }
}
int main()
{
    int i;
    cin >> n;
    for (i = 0; i < n;i++)
    {
        cin >> A[i].begin >> A[i].end;
    }
    solve();
    cout << cnt << endl;
}

田忌赛马

时限:1000ms 内存限制:10000K 总时限:3000ms

描述

田忌与齐王赛马,双方各有n匹马参赛(n<=100),每场比赛赌注为1两黄金,现已知齐王与田忌的每匹马的速度,并且齐王肯定是按马的速度从快到慢出场,现要你写一个程序帮助田忌计算他最好的结果是赢多少两黄金(输用负数表示)。
Tian Ji and the king play horse racing, both sides have n horse (n is no more the 100), every game a bet of 1 gold, now known king and Tian Ji each horse’s speed, and the king is definitely on the horse speed from fast to slow, we want you to write a program to help Tian Ji his best result is win the number gold (lost express with the negative number).

输入

多个测例。
每个测例三行:第一行一个整数n,表示双方各有n匹马;第二行n个整数分别表示田忌的n匹马的速度;第三行n个整数分别表示齐王的n匹马的速度。
n=0表示输入结束。
A plurality of test cases.
Each test case of three lines: the first line contains an integer n, said the two sides each have n horse; second lines of N integers n Tian Ji horse speed; third lines of N integers King n horse speed.
N = 0 indicates the end of input.

输出

每行一个整数,田忌最多能赢多少两黄金。
how many gold the tian ji win

输入样例

3
92 83 71
95 87 74
2
20 20
20 20
2
20 19
22 18
3
20 20 10
20 20 10
0

#include <iostream>
#include <algorithm>
#define MAX 101
using namespace std;
int n;
int a[MAX];
int b[MAX];
int cnt;
int e;
bool compare(int a,int b)
{
    return a > b;
}
void solve()
{
    sort(a, a + n, compare);
    sort(b, b + n, compare);
    int a1 = 0;
    int b1 = 0;
    int m1 = n - 1;
    int n1 = n - 1;
    int t = 0;
    while(a1 <= m1)
    {
        if(a[m1] > b[n1])
        {
            m1--;
            n1--;
            t++;
        }
        else if(a[m1] < b[n1])
        {
            m1--;
            b1++;
            t--;
        }
        else if(a[a1] > b[b1])
        {
            a1++;
            b1++;
            t++;
        }
        else{
            if(a[m1] > b[b1])
            {
                m1--;
                b1++;
                t++;
            }
            else if(a[m1] < b[b1])
            {
				b1++;
				m1--;
				t--;
            }
            else{
                b1++;
                m1--;
            }
        }
    }
    cnt = t;
}
void input()
{
    int i;
    for (i = 0; i < n;i++)
    {
        cin >> a[i];
    }
    for (i = 0; i < n;i++)
    {
        cin >> b[i];
    }
}
int main()
{
    while(cin>>n,n)
    {
        input();
        solve();
        cout << cnt << endl;
        cnt = 0;
        e = 0;
    }
}
  • 7
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Alfred young

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值