A 、Peak 4024
题目大意:
给n个数,判断这n个数,从峰值处,峰值向右依次递减,峰值向左依次递减。符合输出Yes,不符合输出No
代码:
#include<cstdio>
#include<iostream>
#include<cmath>
using namespace std;
int a[100010];
int main()
{
int n,T;
int maxn,k;
while(scanf("%d",&T)!=EOF){
while(T--){
scanf("%d",&n);
scanf("%d",&a[0]);
maxn=a[0];//maxn的初始值为数组的的第一个数
k=0;
int flag=1;
for(int i=1;i<n;i++){
scanf("%d",&a[i]);
if(maxn<a[i]){maxn=a[i];k=i;}//更新最大值与下标
}
for(int i=k;i>0;i--){
if(a[i]<=a[i-1]){//峰值向右,若前方的大于等于后方的,一定不符合
flag=0;
break;
}
}
if(flag){
for(int i=k;i<n-1;i++){
if(a[i]<=a[i+1]){//峰值左侧,若后方的大于等于前方的,一定不符合
flag=0;
break;
}
}
}
if(k==0||k==n-1)flag=0;//特别的,要注意一下,峰值在第一个位置,和最后一个位置的情况
if(flag) printf("Yes\n");
else printf("No\n");
}
}
}
另一份更简洁的代码:
#include<cstdio>
#include<iostream>
#include<cmath>
using namespace std;
const int INF=0x3f3f3f3f,maxn=100005;
int T,n,a[maxn];
int main()
{
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
for(int i=1;i<=n;i++)scanf("%d",&a[i]);
int l=1,r=n;
while(l<n&&a[l]<a[l+1])l++;
while(r>1&&a[r-1]>a[r])r--;
if(l==r&&l>1&&l<n)printf("Yes\n");
else printf("No\n");
}
return 0;
}
B 、King of Karaoke 4025
题目大意:
给一个数值n,接下来有两组n个数值,给第一组值可以任加一个数(可正可负),问最后,两组数据中,最多有几个数相等。
所以,可以对两组数据做差,差相同的个数最多的,即最后可以得到的最大数值。
代码:
#include<iostream>
#include<cstdio>
#include <map>
using namespace std;
const int maxn = 100010;
int a[maxn],b[maxn];
map<int,int>mp;
int main()
{
int T;
cin >> T;
while(T--)
{
int n;
int ans = 0;
cin >> n;
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
}
for(int i=1;i<=n;i++)
{
scanf("%d",&b[i]);
}
for(int i=1;i<=n;i++)
{
int x = a[i]-b[i];
mp[x]++;
if(mp[x]>ans)
ans=mp[x];
}
cout << ans << endl;
mp.clear();
}
return 0;
}
ceil函数:返回大于或者等于指定表达式的最小整数 ; floor函数:返回小于或者等于指定表达式的最大整数。
头文件 : math.h
double ceil(double x) ceil(10.5) == 11 ceil(-10.5) ==-10 (向上取整)
double floor(double x) floor(10.5) == 10 floor(-10.5) == -11(向下取整)
ceil()是向正无穷大舍入,ceil(-10.5) == -10; floor()是向负无穷大舍入,floor(-10.5) == -11;
F:Now Loading!!! 4029
题目大意:
L 、Doki Doki Literature Club 4035
题目大意:
给了n组数据,但就能选k种,在选择时,优先选择幸福值最高的,按选择的顺序输出字符串。
幸福值的计算看题意中的公式。
代码:
#include<iostream>
#include<cstdio>
#include <map>
#include<algorithm>
using namespace std;
struct node{
string s;
long long int m;
}p[110];
int cmp(node a,node b)
{
if(a.m==b.m) return a.s<b.s;
else return a.m>b.m;
}
int main()
{
long long int T;
long long int n,k;
while(scanf("%lld",&T)!=EOF){
while(T--){
long long int sum=0;//用 long long 型
scanf("%lld%lld",&n,&k);
for(int i=0;i<n;i++){
cin>>p[i].s>>p[i].m;
}
sort(p,p+n,cmp);
for(int i=0;i<k;i++)
sum+=(k-i)*p[i].m;
printf("%lld ",sum);
for(int i=0;i<k-1;i++)
cout<<p[i].s<<" ";
cout<<p[k-1].s<<endl;
}
}
return 0;
}
M 、Lucky 7 4036
题目大意:给数值n和k,然后接下来有n个数值,问在这n个数值中,是否有1个数值与k相加,能整除7。至少有一个就可以输出Yes。
代码:
#include<cstdio>
#include<iostream>
#include<cmath>
using namespace std;
int a[100010];
int main()
{
int T;
int n,k;
while(scanf("%d",&T)!=EOF){
while(T--){
int flag=0;
scanf("%d%d",&n,&k);
for(int i=0;i<n;i++)
{
scanf("%d",&a[i]);
if((a[i]+k)%7==0){
flag=1;
}
}
if(flag) printf("Yes\n");
else printf("No\n");
}
}
return 0;
}
J、CONTINUE...? 4033 参考链接
题目大意:
给n个人,编号为1~n,编号数对应每个人拥有的宝石数。接下来的一行中,0表示女生,1表示男生。这n个人一共可分为四组(不一定非要有四组),G1,G2 均为女生, G3 , G4均为男生。
要求最后 G1 + G3 = G2 + G4。 即:使其中女生中的一组 与 男生中的一组 权值的和 等于 总权值的一半。
思路:
当 i >= 0 && i < n/2 时,将标记为0的男生分到三组,女生分到一组。
当 i >= n/2 时,将标记为1的男生分到三组,女生分到一组。
将1、3组的权值相加,将2、4组的权值相加,看最后两者之和是否相同,不相同输出 -1 , 若相同则输出相对应的编号。
如下例:
权值:1 2 3 4 5 6 7 8
原始:1 0 0 1 1 0 1 0
标记:0 1 0 1 0 1 0 1
分组:3 2 1 4 4 1 4 1
代码:
#include<cstdio>
#include<iostream>
using namespace std;
char a[100010];
int vis[100010];
int main()
{
int T,n;
while(scanf("%d",&T)!=EOF){
while(T--){
int sum0=0;int sum1=0;
scanf("%d",&n);
scanf("%s",a);
for(int i=0;i<n/2;i++){
if(i%2==0) {vis[i]=0;sum0+=i+1;}
else {vis[i]=1;sum1+=i+1;}
}
for(int i=n/2;i<n;i++){
if(i%2==0) {vis[i]=1;sum1+=i+1;}
else {vis[i]=0;sum0+=i+1;}
}
if(sum0!=sum1) {cout<<-1<<endl;continue;}
for(int i=0;i<n;i++){
if(a[i]=='1'){
if(vis[i]) cout<<4;
else cout<<3;
}
else{
if(vis[i]) cout<<2;
else cout<<1;
}
}
cout<<endl;
}
}
return 0;
}