aaaaa题解

A [移除数组中的重复元素]

记录出现的数字的个数即可,需注意数字范围 -1000~1000,将数组开为2005,输入一个数标记a[1000 + n]

#include<iostream>
using namespace std;
int a[2005];

int main()
{
    int n, t, ans = 0;
    cin >> n;
    while (n--) {
        cin >> t;
        if (!a[t + 1000]) {ans++; a[t + 1000] = 1;}
    }
    cout <<ans;
    return 0;
}

B [最后一个单词的长度]

在输入时不断更新结果

#include<iostream>
#include<string>
using namespace std;

int main()
{
    int len;
    string a;
    while(cin >> a) {
        len = a.length();
    }
    cout << len;
    return 0;
}

C [最远距离]

数据不大,算出所有距离直接枚举每一个距离即可,输出为四位小数

#include<iostream>
#include<cmath>
#include<cstdio>
using namespace std;
#define MAX 1005
struct wh {
    double x;
    double y;
} m[MAX];
int main()
{
    double ans = -1;
    int n;
    cin >> n;
    for (int i = 0; i < n; i++) {
        cin >> m[i].x >> m[i].y;
    }
    for (int i = 0; i < n - 1; i++) {
        for (int j = i + 1; j < n; j++) {
            ans = max(ans, sqrt((m[i].x - m[j].x) * (m[i].x - m[j].x) + (m[i].y - m[j].y) * (m[i].y - m[j].y)));
        }
    }
    printf("%.4lf", ans);
    return 0;
}

D [拦截导弹]

由于下一次拦截的导弹不能高过上一个,所以题为寻找最长下降序列 (但是可以等于上一次。。)

#include<algorithm>
#include<iostream>
#include<cstdio>
using namespace std;
#define MAX 30
int dp[MAX];
int main()
{
    int n, a[30], ans = -1;
    cin >> n;
    for (int i = 0; i < n; i++) {
        cin >> a[i];
        dp[i] = 1;
    }
    for (int i = 0; i < n; i++) {
    	//递推从前检视最大长度
        for (int j = 0; j < i; j++) {
            if(a[i] <= a[j]) dp[i] = max(dp[j] + 1, dp[i]);
        }
        ans = max(ans, dp[i]); //更新答案
    }
    cout << ans;
    return 0;
}

nlogn的写法还不会。。

E [简单的整数划分]

n为目标划分数,m为所有加数中最大的一个
1. 若n和m的其中一个等于1,意味递归到达终点,并且这是一种情况
2. 若n和m其中一个小于1,同样是递归终点,但是这种情况是不符合的
3. 如果n == m,那么他的值为(n, m - 1)这种情况加上1,加上的1代表最大加数为n
4. 如果m大于n,显然,这种情况是不可能发生的,但是这不代表来到终点,因为如果最大加数大于n,那么它也可以等于n,所以这种情况可以看作(n, n)
5. 最后是正常情况,n > m,这时的值等于(n - m, m) + (n, m - 1),若使用m值,剩余的值是n - m,再对剩下的值和m作判断;另外一种情况,不使用m值,n的值不变,改变m值,减少最大加数,判断(n, m - 1)

#include<iostream>
using namespace std;

int ans(int n, int m)
{
    if (n == 1 || m == 1) return 1;  
    //if (n < 1 || m < 1) return 0;
    if (n == m) return ans(n, m - 1) + 1;
    if (m > n) return ans(n, n);
    return ans(n - m, m) + ans(n, m - 1);
}

int main()
{
    int n;
    while (cin >> n)
        cout << ans(n, n) <<endl;
    return 0;
}

F [登山]

先往上爬再往下爬,就是最长上升序列加上这个点之后的最长下降子序列

#include<algorithm>
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
using namespace std;
#define MAX 1005
int up[MAX], down[MAX], m[MAX];

int main()
{
    int ans = -1;
    int n;
    cin >> n;
    for (int i = 0; i < n; i++) {
        up[i] = 1; down[i] = 1;
        cin >> m[i];
    }
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < i; j++) {
            if (m[i] > m[j]) up[i] = max(up[j] + 1, up[i]);
        }
    }
    //这里需要倒序递推最长上升子序列,才能保证从前往后看时到那个点是该点之后的下降序列的长度
    for (int i = n - 1; i >= 0; i--) {  
        for (int j = n - 1; j >= i; j--) {
            if (m[i] > m[j]) down[i] = max(down[j] + 1, down[i]);
        }
    }
    for (int i = 0; i < n; i++){
    	//需要减1.因为都算上了i这个点
        ans = max(ans, up[i] + down[i] - 1);
    }
    cout << ans;
    return 0;
}

G [滑雪]

找出一条最长的下降路,将每个点的高度,行列存进结构体,再用高度对结构体排序,然后再检视上下左右更新每一个点,如果一个点比上下左右的一些点高,那么那些点的值为他们当前的值或当前这个点的值+1,最后输出最大值即可

#include<bits/stdc++.h>
using namespace std;
#define MAX 10000
int walk[MAX][MAX], spead[MAX], ans[MAX][MAX];

struct all {
    int colu;
    int row;
    int high;
}highl[MAX];

bool cmp (all x, all y)
{
    return x.high > y.high;
}

int main()
{
    int colu, row, flag = 1, num, x, y, maxn;
    cin >> row >> colu;
    num = row * colu;
    for (int i = 1; i <= row; i++) {
        for (int j = 1; j <= colu; j++) {
            ///输入,并把行列号存入结构体
            cin >> walk[i][j];
            ans[i][j] = 1;
            highl[flag].colu = j;
            highl[flag].row = i;
            highl[flag].high = walk[i][j];
            flag++;
        }
    }
    ///按高度从高到低对结构体排序
    sort (highl + 1, highl + flag, cmp);


    for (int i = 1; i <= num; i++) {
        ///检视上下左右,横纵坐标从结构体中取
        if (walk[highl[i].row] [highl[i].colu] > walk[highl[i].row] [highl[i].colu - 1]) ans[highl[i].row] [highl[i].colu - 1] = max(ans[highl[i].row] [highl[i].colu - 1], ans[highl[i].row][highl[i].colu] + 1);
        if (walk[highl[i].row] [highl[i].colu] > walk[highl[i].row] [highl[i].colu + 1]) ans[highl[i].row] [highl[i].colu + 1] = max(ans[highl[i].row] [highl[i].colu + 1], ans[highl[i].row][highl[i].colu] + 1);
        if (walk[highl[i].row][highl[i].colu] > walk[highl[i].row - 1][highl[i].colu]) ans[highl[i].row - 1][highl[i].colu] = max(ans[highl[i].row - 1][highl[i].colu], ans[highl[i].row][highl[i].colu] + 1);
        if (walk[highl[i].row][highl[i].colu] > walk[highl[i].row + 1][highl[i].colu]) ans[highl[i].row + 1][highl[i].colu] = max(ans[highl[i].row + 1][highl[i].colu], ans[highl[i].row][highl[i].colu] + 1);
    }
    maxn = ans[1][1];
    int a, b;
    for (int i = 1; i <= row; i++)
        for (int j = 1; j <= colu; j++)
            if (maxn <= ans[i][j]) {maxn = ans[i][j]; a = i; b = j;}
    cout << maxn;
    return 0;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值