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;
}