1)求和
两两相乘,在求和
表面上看这是一道暴力求和的题,用两层循环。但是实际上是这是一道 前缀和的题目。暴力会超时。
解题思路,每个数都要乘与比自己大的数。换个角度看就是每个数都要乘与比自己小的数,二者等价。正好可以用前缀和求解。
#include <iostream>
#define MAXN 200001
using namespace std;
long long n,ret=0;//注意题目说了选择合适的数据类型
long long num[MAXN],sum[MAXN];
int main(){
cin>>n;
for(int i=1;i<=n;i++){
cin>>num[i];
sum[i]=sum[i-1]+num[i];
}
for(int i=2;i<=n;i++){
ret+=(sum[i]-num[i])*num[i];
}
cout<<ret;
}
2)赢球票
该题通过遍历所有可能的起点,通过一个计数器累加,注意用vis数组来表示该牌有没有被取走
#include <bits/stdc++.h>
using namespace std;
int num[101];
int vis[101];
int main(){
int n,ret=0;
cin>>n;
for(int i=1;i<=n;i++){
cin>>num[i];
}
for(int i=1;i<=n;i++){
int count=0,cnt=1,x=i,ans=0;//设置count用来记录取走的个数,cnt报数器
memset(vis,0,sizeof(vis));
while(1){
if(!vis[x]){
if(num[x]==cnt){
ans+=cnt;
count++;
cnt=0;
vis[x]=1;
}
cnt++;
}
x++;
if(x==n+1)x=1;
if(count==n|cnt>n)break;//注意跳出循环的条件
}
if(ans>ret)ret=ans;
}
cout<<ret;
}
3)解迷游戏
这道B组国赛题,实际上只要观察出原理,就不难写出代码。
通过轮转我们可以发现,内圈0位置的塑料棒只能和外圈的三个塑料棒交换,只能和中圈的两个塑料棒交换
如图:
因此我们只需遍历内圈四根塑料棒,判断每一种情况下这六根塑料棒是否满足3绿2红1黄,如不满足则直接输出“NO”。
这里用到一个小技巧用一个数组---“桶”来记录不同颜色塑料棒出现的次数。
#include <bits/stdc++.h>
using namespace std;
int ret[100];
int main(){
int T;
cin>>T;
while(T--){
string a,b,c;
bool flag=true;
cin>>a>>b>>c;
memset(ret,0,sizeof(ret));
for(int i=0;i<4;i++){
ret[a[i]]++;
ret[b[i]]++;
ret[c[i]]++;
ret[a[i+4]]++;
ret[a[i+8]]++;
ret[b[i+4]]++;
if(ret['G']!=3||ret['R']!=2||ret['Y']!=1){
flag=false;
break;
}
}
if(flag){
cout<<"YES"<<"\n";
}else cout<<"NO"<<"\n";
}
}
4)双子数
首先确定p,q的取值范围,由平方可知。p,q肯定小于23333333333333的开放,取值大约在1~1e7左右。
在1~1e7中筛选质数,可以用“埃氏筛”
已知任何一个和数都有一个质因数小于该和数的开方,因此我们只需要筛选出“1e7开方”中的素数就可以遍历出所有在1e7中的和数,从而只剩下质数
long long a = 2333, b = 23333333333333, ret = 0;
for (int i = 2; i <=sqrt(N); i++) {//筛选出该范围的质数
if (cnt[i] == 0) {若为质数
for (int j = i * i; j <= N; j += i) {
//开始筛选和数,至于为什么不从2*i开始筛选是因为,2以前已经作为i被筛选过了
cnt[j] = 1;
}
}
}
int cur = 0;
for (int i = 2; i <= N; i++) {
if (!cnt[i])isprime[cur++] = i;//将素数加入数组
}
for (int i = 0; i < cur; i++) {
long long p1 =1LL* isprime[i] * isprime[i];
if (1LL*p1 * p1 > b)break;
for (int j = i + 1; j < cur; j++) {
long long p2 =1LL*isprime[j] * isprime[j];
if (1LL*p1 * p2 < a)continue;
if (1LL*p1 * p2 > b)break;
ret++;
}
}
cout << ret;