1
问题描述
两个二进制数11110011101和1111101001的和是多少?请用二进制表示,注意在提交的时候不要提交前导0。
答案提交
这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个二进制数,在提交答案时只填写这个二进制数,填写多余的内容将无法得分。
x=0b11110011101
y=0b1111101001
print(x)
print(y)
print(x+y)
a=x+y
print(bin(a))
2
问题描述
不超过19000的正整数中,与19000互质的数的个数是多少?
答案提交
这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。
#include <iostream>
using namespace std;
int euler(int n){
int res=n;
for(int i=2;i*i<=n;i++){
if(n%i==0){
res=res/i*(i-1);
while(n%i==0){
n/=i;
}
}
}
if(n>1){
res=res/n*(n-1);
}
return res;
}
int main() {
int n;
cin>>n;
cout<<euler(n);
return 0;
}
3
问题描述
一棵包含有2019个结点的树,最多包含多少个叶结点?
答案提交
这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。
没啥说的
2018
4
问题描述
由1对括号,可以组成一种合法括号序列:()。
由2对括号,可以组成两种合法括号序列:()()、(())。
由4对括号组成的合法括号序列一共有多少种?
答案提交
这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。
直接计算C74
35种
5
问题描述
给定一个单词,请计算这个单词中有多少个元音字母,多少个辅音字母。
元音字母包括 a, e, i, o, u,共五个,其他均为辅音字母。
输入格式
输入一行,包含一个单词,单词中只包含小写英文字母。
输出格式
输出两行,第一行包含一个整数,表示元音字母的数量。
第二行包含一个整数,表示辅音字母的数量。
样例输入
lanqiao
样例输出
4
3
评测用例规模与约定
对于所有评测用例,单词中的字母个数不超过100。
#include<iostream>
#include <cstdio>
#include <cmath>
#include<string>
#include<cstring>
using namespace std;
#define ARRAY_NUM 105
int main(void)
{
char c [ARRAY_NUM]={0};
int count=0,i,k=0;
gets(c);
for(i=0;i<=ARRAY_NUM;i++)
{
if(c[i]==10)
break;
if(c[i]=='a'||c[i]=='e'||c[i]=='i'||c[i]=='o'||c[i]=='u')
{
count++;
}
}
int len=strlen(c);
printf("%d\n",count);
cout<<len-count<<endl;
}
6
问题描述
在数列 a_1, a_2, …, a_n中,如果 a_i 和 a_j 满足 i < j 且 a_i > a_j,则称为一个逆序数对。
给定一个数列,请问数列中总共有多少个逆序数对。
输入格式
输入的第一行包含一个整数 n。
第二行包含 n 个整数 a_1, a_2, …, a_n,相邻的整数间用空格分隔,表示给定的数列。
输出格式
输出一行包含一个整数,表示答案。
样例输入
6
3 1 5 2 3 5
样例输出
4
评测用例规模与约定
对于 50% 的评测用例,1 <= n <= 100,0 <= 数列中的数 <= 1000。
对于所有评测用例,1 <= n <= 1000,0 <= 数列中的数 <= 10000。
一眼dp 套用求LCS的思想,求LIS
定义数组时,全部初始化为1,初始状态表示的是最坏的情况,以v[i]结尾的最长递增子序列就是v[i]它本身,长度为1。接着将v[i]逐一与前面的数字v[x]进行比较,x∈[0,i),若发现v[x]<v[i],说明v[i]可作为后继元素增加到以v[x]结尾的递增子序列中,则a[i]=v[x]+1,但是在将v[i]逐一与v[x]进行比较的过程中,我们需要找出最大的v[i],所以将每一次v[i]需要更新的值与它本身的值进行比较,取大的那一个就行了,保持在每一次v[i]与v[x]比较之后,v[i]的值都是最大的。最后,找出数组v中最大值就是结果。
再来看看样例,a[0]~a[5]的初始值都是1,首先求以v[1]结尾的最长递增子序列长度。v[1]>v[0],说明4可作为1的后继成为递增序列,以1结尾的递增序列长度a[0]为1(默认值),则a[1]可以等于a[0]+1,同时a[1]本身也是1,a[0]+1>a[1],所以最终a[1]=a[0]+1=2;接着求v[2]结尾的最长递增子序列长度,将v[2]与v[0]进行比较,v[2]>v[0]同时a[0]+1>a[2],所以a[2]=a[0]+1=2;将v[2]与v[1]进行比较,v[2]<v[1],则a[2]的值不变,最终a[2]=2;接着求v[3]结尾的最长递增子序列长度,v[3]>v[0]且a[0]+1>a[3],a[3]=a[0]+1=2;v[3]<v[1],a[3]值不变为2;v[3]<v[2],v[3]值不变为2,所以最终a[3]的值为2。后面的v[4]与v[5]依此类推。
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main(){
int n;
cin>>n;
vector<int> v(n);
vector<int> a(n,1);
for(int i=0;i<n;i++)
cin>>v[i];
for(int i=1;i<n;i++)
for(int j=0;j<i;j++)
if(v[i]>v[j])
a[i]=max(a[i],a[j]+1);
sort(a.begin(),a.end());
cout<<a[n-1];
return 0;
}
7
问题描述
在数列 a_1, a_2, …, a_n中,如果 a_i 和 a_j 满足 i < j 且 a_i > a_j,则称为一个逆序数对。
给定一个数列,请问数列中总共有多少个逆序数对。
输入格式
输入的第一行包含一个整数 n。
第二行包含 n 个整数 a_1, a_2, …, a_n,相邻的整数间用空格分隔,表示给定的数列。
输出格式
输出一行包含一个整数,表示答案。
样例输入
6
3 1 5 2 3 5
样例输出
4
评测用例规模与约定
对于 50% 的评测用例,1 <= n <= 100,0 <= 数列中的数 <= 1000。
对于所有评测用例,1 <= n <= 1000,0 <= 数列中的数 <= 10000。
就是求前面数的比后面的数大的个数
采用树状数组的数据结构
首先我们要知道树状数组是什么,都知道树状数组它可以用来求解相应区间的和,以及修改一定区间的数据内容。那么我们可以利用这个性质来计算数组中的逆序数。
在树状数组中我们每次网相应的数组中添加的是哪一个数的具体数值,
我们只需要在这个地方稍微变动一下,我们就可以把它转换成计算逆序数:
我们每次都是在这个数字大小的位置上添加1,然后去更新树状数组,
在计算逆序数的时候,只需要查看一下比这个数小或等于的数有多少个,
然后现在的位数减去前面比它小的就是所得这一位的逆序数。
#include<iostream>
#include<cstdlib>
#include<string>
#include<cstring>
#include<cstdio>
using namespace std;
const int maxn = 100000+10;
int a[maxn];
int main()
{
memset(a,0,sizeof(a));
int t,n;
long long sum=0;
scanf("%d",&n);
for(int i=0;i<n;i++)
{
scanf("%d",&t);
sum =sum+ a[t];
for(int j=0;j<t;j++)
a[j]++;
}
printf("%lld\n",sum);
return 0;
}
}
8
问题描述
一个平面向量表示从一个坐标点到另一个坐标点的变化量,一般用两个数 (x, y) 来表示。
两个向量相加是指分别将对应的两个数相加,例如 (x_1, y_1) 与 (x_2, y_2) 相加后得 (x_1+x_2, y_1+y_2)。
如果两个向量相加后,得到的向量两个值相等,我们称这两个向量为和谐向量对。例如 (3, 5) 和 (4, 2) 是和谐向量对。
给定 n 个向量,问能找到多少个和谐向量对?
输入格式
输入的第一行包含一个整数 n,表示向量的个数。
接下来 n 行,每行两个整数 x_i, y_i,表示一个向量。
输出格式
输出一行,包含一个整数,表示有多少个和谐向量对。
请注意,自己和自己不能成为一个和谐向量对。
样例输入
5
9 10
1 3
5 5
5 4
8 6
样例输出
2
样例输入
4
1 1
2 2
1 1
2 2
样例输出
6
样例说明
每两个向量组成一个和谐向量对。
评测用例规模与约定
对于 70% 的评测用例,1 <= n <= 1000;
对于所有评测用例,1 <= n <= 100000,-1000000 <= x_i, y_i <= 1000000。
请注意答案可能很大,可能需要使用 long long 来保存。
题解1
这题排序是对x排序 顺带改变y 别排错了
不过还是要注意时间
感觉和第五题差不多 也是
维护两个数组
分别是最长上升子序列的长度
和最长下降子序列的长度(倒序搜索)
同第五题
9
问题描述
给定一个序列 a_1, a_2, …, a_n。其中 a_1 是最大的数,没有其他数与 a_1 相等。
对于从第二个数开始的每个数 a_i,请找到位置在 a_i 之前且比 a_i 大的,位置上距离 a_i 最近的数 a_j。称 i-j 为 a_i 的前向距离。
对于给定的序列,请求出所有数的前向距离之和。
输入格式
输入的第一行包含一个整数 n,表示序列的长度。
第二行包含 n 个正整数,为给定的序列。
输出格式
输出一个整数,表示序列中所有数的前向距离之和。
样例输入
8
9 1 3 5 2 7 6 3
样例输出
14
样例说明
序列中从第二项开始的前向距离依次为:
1, 2, 3, 1, 5, 1, 1
和为14。
数据规模和约定
对于70%的评测用例,1 <= n <= 1000;
对于所有评测用例,1 <= n <= 100000,a_1 <= 1000000。
请注意答案可能很大,可能需要使用 long long 来保存。
这种题我也不太会,那可太不会了
像kmp 又像并查集
题解1
标准解法——并查集
一个数组prev表示前一个比当前数大的索引
然后后面的数比到这个数的时候如果相等就不用一路比回去了
极端情况下还是会超时 比如已知升序且无重复
[9999999, 1, 2, ..., 9999998]
优化一下:
···
prev[j]表示j之前离j最近比a[j]大的索引
那么a[j]肯定比从prev[j] + 1 到j - 1都大
所以当a[i] > a[j]时 [j, i - 1]范围内的元素都比a[i]小
[prev[j], j - 1]范围内的元素都比a[j]小
所以也一定比a[i]小
所以从prev[j]到j - 1可以直接跳
j直接跳到prev[j]即可接着查
10
问题描述
小明要组织一台晚会,总共准备了 n 个节目。然后晚会的时间有限,他只能最终选择其中的 m 个节目。
这 n 个节目是按照小明设想的顺序给定的,顺序不能改变。
小明发现,观众对于晚上的喜欢程度与前几个节目的好看程度有非常大的关系,他希望选出的第一个节目尽可能好看,在此前提下希望第二个节目尽可能好看,依次类推。
小明给每个节目定义了一个好看值,请你帮助小明选择出 m 个节目,满足他的要求。
输入格式
输入的第一行包含两个整数 n, m ,表示节目的数量和要选择的数量。
第二行包含 n 个整数,依次为每个节目的好看值。
输出格式
输出一行包含 m 个整数,为选出的节目的好看值。
样例输入
5 3
3 1 2 5 4
样例输出
3 5 4
样例说明
选择了第1, 4, 5个节目。
评测用例规模与约定
对于 30% 的评测用例,1 <= n <= 20;
对于 60% 的评测用例,1 <= n <= 100;
对于所有评测用例,1 <= n <= 100000,0 <= 节目的好看值 <= 100000。
我本来以为最后一题 我一瞅 最起码是个贪心吧 不是
排序就完了
#include<iostream>
#include<cstdlib>
#include<string>
#include<cstring>
#include<cstdio>
#include<algorithm>
bool cmp(int a,int b)
{
return a>b;
}
using namespace std;
int main()
{
int n,m;
cin>>n>>m;
int *a=new int[n];
for(int i=0;i<n;i++)
{
cin>>a[i];
}
sort(a,a+n,cmp);
for(int i=m-1;i>=0;i--)
cout<<a[i]<<" ";
return 0;
}