1001
预处理前缀和,一旦有两个数模m的值相同,说明中间一部分连续子列可以组成m的倍数。 另外,利用抽屉原理,我
们可以得到,一旦n大于等于m,答案一定是YES 复杂度 O(n)
#include<stdio.h>
#include<string.h>
#include<iostream>
#include<queue>
#include<stack>
#include<map>
#include<vector>
#include<math.h>
#include<algorithm>
using namespace std;
int a[100010];
int main(){
int T;
scanf("%d",&T);
while(T--){
int n,m;
scanf("%d%d",&n,&m);
bool s = false;
for(int i=0;i<n;i++){
scanf("%d",&a[i]);
if(a[i]%m==0) s = true;
}
if(n>m) s = true;
if(!s){
long long temp = 0;
map<int ,int >mm;
for(int i=0;i<n;i++){
temp += a[i];
mm[temp%m]++;
if(temp%m==0||mm[temp%m]>=2){
s = true;
break;
}
}
}
printf("%s\n",s?"YES":"NO");
}
return 0;
}
1002
首先骨牌只要考虑都往右推,其次能带倒骨牌的前提是高度大于等于距离+1。所以如果推一次,那么就是骨牌高度=
离下一块骨牌距离+1. 把第一块左边距离设为无穷大,能推nk次,那么就是找nk块左边距离最大的向右推倒即可,所
以只需要排序找到前nk-1大的距离。 有个小trick,推的次数可能大于骨牌数量 复杂度 O(nlogn)
#include<stdio.h>
#include<string.h>
#include<iostream>
#include<queue>
#include<stack>
#include<map>
#include<vector>
#include<math.h>
#include<algorithm>
using namespace std;
int main(){
int T;
scanf("%d",&T);
while(T--){
int n,k;
scanf("%d%d",&n,&k);
priority_queue<int>q;
long long r = n;
for(int i=0;i<n-1;i++){
int t;
scanf("%d",&t);
q.push(t);
}
if(k<n){
for(int i=0;i<k-1;i++) q.pop();
while(!q.empty()){
r += q.top();
q.pop();
}
}
printf("%I64d\n",r);
}
return 0;
}
1003
由于y质因数分解式中每个质因数均出现2次,那么y是一个完全平方数,设y=z*z,题目可转换成求z,使得每个质因
数出现1次. 我们可以暴力枚举z,检查z是否符合要求,显然当z是质数是符合要求,由素数定理可以得,z的枚举量在
logn级别 复杂度 O(4√nlog2√n)
#include<stdio.h>
#include<string.h>
#include<iostream>
#include<queue>
#include<stack>
#include<map>
#include<vector>
#include<math.h>
#include<algorithm>
using namespace std;
#define N 50050
int n;
int prime[N];
void Get_prime(){
bool t[N];
memset(t,false,sizeof(t));
n = 0;
for(int i=2;i<N;i++){
if(!t[i]){
prime[n++] = i;
for(int j=i+i;j<N;j+=i) t[j] = true;
}
}
}
bool check(long long x){
for(int i=0;i<n;i++){
int count = 0;
while(x%prime[i]==0){
count++;
x/=prime[i];
if(count>=2) return false;
}
}
return true;
}
int main(){
int T;
scanf("%d",&T);
Get_prime();
while(T--){
long long x;
scanf("%I64d",&x);
if(x<4){
printf("%d\n",abs(x-4));
}
else{
long long p,q;
long long temp = sqrt(x);
for(int i=0;;i--){
if(check(i+temp)){
p = i+temp;
break;
}
}
for(int i=1;;i++){
if(check(i+temp)){
q = i+temp;
break;
}
}
printf("%I64d\n",min(abs(p*p-x),abs(q*q-x)));
}
}
return 0;
}