CodeCraft-20 (Div. 2) A-C

A

水题,没啥好讲的。具体见代码

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e3+5;
int t,n,m;
int a[maxn];
ll ans,sum;
int main(){
	cin>>t;
	while(t--){
		cin>>n>>m;
		sum=0;
		for(int i=0;i<n;i++){
			cin>>a[i];
			sum+=a[i];
		}
		if(sum<=m) ans=sum;
		else ans=m;
		cout<<ans<<'\n';
	}
	return 0;
}

B

这题很绕,具体点就是翻转。
我们得找到两个规律
(1)新串是从s【k-1】开始的。(说明一下,在题目中时k作为下标是从1开始的,但我为了习惯所以下标还是从0开始。因此为k-1)
(2)当k与n同奇偶时 目标串=原串k之后的 + 原串k之前的翻转
当k与n不同奇偶时 目标串=原串k之后的 + 原串k之前的

发现之后就可以轻轻松松的暴力模拟啦。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e3+5;
int t,n,ans;
string s,A,temp,ANS,T;
char mmin;
int main(){
 cin>>t;
 while(t--){
  cin>>n>>s;
  ANS="z";mmin='z';
  A=s+s;//双倍延长 
  for(int i=0;i<n;i++)//找最小开头 
   if((mmin-'a')>(s[i]-'a')) mmin=s[i]; 
  //核心代码 
  for(int i=0;i<n;i++){
   if(mmin==s[i]){
    temp=A.substr(i,n-i); //原串k之前的 
    T=A.substr(n,i);//原串k之后的,未翻转 
    if((i+1)%2==n%2) reverse(T.begin(),T.end());
    //翻转后的串从k开始(这里的k从1开始,代码中的i从0开始) 
    //i+1就是k. 当k与n同奇偶时 目标串=原串k之后的 + 原串k之前的翻转
    // 当k与n不同奇偶时 目标串=原串k之后的 + 原串k之前的
    temp+=T;
    if(ANS=="z"){
     ANS=temp;
     ans=i+1;
    }
    else if(ANS>temp){
     ANS=temp;
     ans=i+1;
    }
   }
  }
  cout<<ANS<<'\n'<<ans<<'\n';
 }
 return 0;
}

C

数学题。

题意:
给出两个本原多项式f(x)和g(x),h(x)=f(x)∗g(x)
然后给出一个素数p,问h(x)中哪一项的系数无法被p整除。

思路:
f(x)和g(x)各自按照x的指数从小到达排列后,
各取第一项无法被p整除的项,系数相乘即为所求系数,序号相加即为答案。

证明:
下面用
设f(x)中第一个无法被p整除的为第i项,系数为A
设g(x)中第一个无法被p整除的为第j项,系数为B
所以 f(x) / g(x) 中前 i-1 / j−1 项均可以被p整除,
而 在 h(x) 中第 i+j 项的指数为 i+j-2 ,系数(用co表示)由两部分组成
(1)f(i) * g(j) co = AB
(2)f(x)前 i-1 项与 g(x)前 j-1 项组合指数和也为 i+j-2 的项,它们的系数的乘积
又因为每一项均可被p整除,所以该部分项 系数的乘积也可被整除.
因此表示为 k
p
最后 co = AB + kp 显然co不被p整除,证毕。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll maxn=2e6+5;
ll n,m,p,ans;
ll a[maxn],b[maxn];
inline int Read() {
    int x=0,f=1; char ch=getchar();
    while (ch<'0'||ch>'9') {if (ch=='-') f=-f; ch=getchar();}
    while (ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
    return x*f;
}
int main(){
	n=Read();m=Read();p=Read();
	for(int i=0;i<n;i++) a[i]=Read();
	for(int i=0;i<m;i++) b[i]=Read();
	for(int i=0;i<n;i++){
		if(a[i]%p){
			ans+=i;
			break;
		}
	}
	for(int i=0;i<m;i++){
		if(b[i]%p){
			ans+=i;
			break;
		}
	}
	printf("%lld\n",ans);
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值