当前位置: 代码迷 >> 综合 >> 2019 浙江省赛(The 16th Zhejiang Provincial Collegiate Programming Contest Sponsored by TuSimple)
  详细解决方案

2019 浙江省赛(The 16th Zhejiang Provincial Collegiate Programming Contest Sponsored by TuSimple)

热度:53   发布时间:2023-12-26 09:39:53.0

目录

B Element Swapping(数学问题)

E Sequence in the Pocket(思维)

F Abbreviation(签到题)

G Lucky 7 in the Pocket(签到题)

H Singing Everywhere(分类讨论+思维)

I Fibonacci in the Pocket(规律+高精度求余)


B Element Swapping(数学问题)

【题意】一个序列,交换第 i 个元素和第 j 个元素,有 x 和 y 的计算公式;给出交换后的序列以及原序列的x和y的值;求可能有多少种交换方法

【分析】数学公式问题

设交换后的序列对应的x、y分别是M,N

那么有

      

所以,只要求出a[i]就可以知道a[j]的值,注意求出的a[i]与a[j]还要满足M,x的关系

如果a[i]=a[j],两两组合,一共有n*(n+1)/2种组合;这种情况特判一下;

其他的情况分类讨论一下即可;注意数组和num是long long的,int的话是会爆的然后就会wa的...

【代码】

#include<bits/stdc++.h>
using namespace std;typedef long long ll;
const int maxn=2e5+10;
ll a[maxn];
map<int,int>mp;int main()
{int t; scanf("%d", &t);while(t--){ll n, x, y;scanf("%lld%lld%lld", &n, &x, &y);ll M = 0, N = 0, ans = 0;mp.clear();for(int i = 1; i <= n; ++i){scanf("%lld", &a[i]);M += i*a[i];N += i*a[i]*a[i];mp[a[i]]++;}if(x == M && y == N){map<int,int>::iterator it;for(it = mp.begin(); it != mp.end(); ++it){ll num = it->second;ans += num*(num-1)/2;}printf("%lld\n", ans);continue;}if(x == M || y == N || (y-N)%(x-M) != 0){printf("0\n");continue;}ll sum = (y-N)/(x-M);for(int i = 1; i <= n; ++i){ll aj = sum - a[i];if(a[i] == aj || aj < 1 || ((x-M) % (a[i]-aj) != 0))continue;int cha = (M - x)/(a[i] - aj);int j = i-cha;if(j <= 0 || j > n || j <= i || a[j] != aj)continue;ans++;}printf("%lld\n", ans);}return 0;
}

E Sequence in the Pocket(思维)

【题意】给你一串序列,每次只能把某个元素移到最前面,问至少要移动多少次使得序列非降

【分析】

一段序列,如果要变成非降序列,那么就要不断维护序列;因为要移动,所以每次都尽量把最大值放在序列后面即尽量不移动最大值;

即先排个序,排序之后每个数的位置其实就固定了,再跟原序列进行比较,如果同一个位置的值不相等,即该数是需要移动的,记录需要移动的位置,输出即可;

【代码】

#include<bits/stdc++.h>
using namespace std;const int maxn=1e5+10;
typedef long long ll;
ll a[maxn],b[maxn];int main()
{int t;scanf("%d",&t);while(t--){int n;scanf("%d",&n);for(int i=0;i<n;++i){scanf("%lld",&a[i]);b[i]=a[i];}sort(a,a+n);int j=n-1;int ans=0;for(int i=n-1;i>=0;--i){if(a[j]==b[i]) --j;else ans++;}printf("%d\n",ans);}return 0;
}

F Abbreviation(签到题)

【题意】去掉读入串中不在首位的'a', 'e', 'i', 'y', 'o', 'u'

【代码】

#include<bits/stdc++.h>
using namespace std;int main()
{int t;scanf("%d",&t);while(t--){string s;cin>>s;int len=s.length();for(int i=0;i<len;++i){if(i==0)printf("%c",s[i]);else{if(s[i]=='a' || s[i]=='e' || s[i]=='i' || s[i]=='o' || s[i]=='u' || s[i]=='y')continue;else printf("%c",s[i]);}}puts("");}return 0;
}

G Lucky 7 in the Pocket(签到题)

【题意】输出比读入的数字大的最小的数(被7整除但不被4整除)

【代码】

#include<bits/stdc++.h>
using namespace std;int main()
{int t;scanf("%d",&t);while(t--){int n;scanf("%d",&n);while(1){if(n%7==0 && n%4!=0){printf("%d\n",n);break;}n++;}}return 0;
}

H Singing Everywhere(分类讨论+思维)

【题意】给出音调的序列,先升后降称为crack,每次最多可以删掉一个音符,问最少要演奏多少个crack

【分析】分类讨论一下即可;

首先统计一下原序列中crack 的总数,然后遍历模拟删掉每个音符的结果

删掉第i个音符时,讨论i+1、i-1 是峰的情况,并且要统计原序列这里的峰的数量,最后相减取最大值即可

注意统计原序列里的峰的数量时,不可以直接if-else if-else if,因为如果是a[i]处于谷的时候,会同时满足a[i-1]和a[i+1]是峰

【代码】

#include<bits/stdc++.h>
using namespace std;const int maxn=1e5+10;
int a[maxn];int main()
{int t;scanf("%d",&t);while(t--){int  n;scanf("%d",&n);for(int i=1;i<=n;++i)scanf("%d",&a[i]);a[0]=a[n+1]=99999999999;int cnt=0;for(int i=2;i<=n-1;++i)if(a[i]>a[i-1] && a[i]>a[i+1])cnt++;int ans=0;for(int i=2;i<=n-1;++i){int n1=0,n2=0;if(a[i]>a[i-1] && a[i]>a[i+1])n1++;if(a[i-1]>a[i-2] && a[i-1]>a[i])n1++;if(a[i+1]>a[i] && a[i+1]>a[i+2])n1++;if(a[i-1]>a[i-2] && a[i-1]>a[i+1])n2++;else if(a[i+1]>a[i-1] && a[i+1]>a[i+2])n2++;//cout<<n1<<","<<n2<<endl;ans=max(ans,n1-n2);}//cout<<"cnt="<<cnt<<",ans="<<ans<<endl;ans=cnt-ans;printf("%d\n",ans);}return 0;
}

I Fibonacci in the Pocket(规律+高精度求余)

【题意】求第a项到第b项斐波那契数列的和是奇数还是偶数

【分析】把斐波那契数列的前几项写出来就会发现,呈 奇数 奇数 偶数 排列;

因为奇数+奇数=偶数,奇数+偶数=奇数,偶数+偶数=偶数

所以根据这个规律,可以把a和b的余数求出来,看对应的是每一块(3个数)的哪个数,然后分类讨论即可

取余的话,和大数除法相同,就是最后输出余数即可(上次被要求手动写写大数的几个运算,果然印象深刻了许多!)

【代码】

#include<bits/stdc++.h>
using namespace std;int getMod(string s,int x)
{// string ans;int len=s.length();int d=0;for(int i=0;i<len;++i){int num=s[i]-'0';int tmp=(d*10+num)/x;//   ans+=tmp+'0';d=d*10+num-tmp*x;}// cout<<"d="<<d<<endl;return d;
}
int main()
{int t;scanf("%d",&t);while(t--){string a,b;cin>>a>>b;int n1=getMod(a,3);int n2=getMod(b,3);if(n1==1 && n2==1)printf("1\n");else if(n1==2 && (n2==2|| n2==0))printf("1\n");else if(n1==0 && n2==1)printf("1\n");else printf("0\n");}return 0;
}

 

  相关解决方案