-
签到题
AC代码
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int maxn = 1e5 + 5; bool f(int n){ for(int i = 2; i*i <= n; i++){ if(n%i==0) return 0; } return 1; } int main(void) { int n; cin >> n; for(int i = 2; i*i <= n; i++){ if(n%i==0){ int t = n/i; if(f(t)){ cout<<t<<endl; break; } } } return 0; }
-
签到题
AC代码
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int maxn = 1e5 + 5; bool f(int n){ for(int i = 2; i*i <= n; i++){ if(n%i==0) return 0; } return 1; } int main(void) { int n; while(cin>>n&&n){ for(int i = 2; i <= n/2; i++){ if(f(i)&&f(n-i)){ cout<<n<<" = "<<i<<" + "<<n-i<<endl; break; } } } return 0; }
-
G - Sherlock and His Girlfriend【思维】
思路:质数输出0,合数输出1.
AC代码
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int maxn = 1e5 + 5; bool book[maxn]; void Init(){ for(int i = 2; i <= maxn; i++){ if(book[i]==0){ for(int j = i+i; j <= maxn; j += i){ book[j] = 1; } } } } int main(void) { int n; cin >> n; Init(); if(n==1){ cout<<1<<endl; cout<<1<<endl; } else if(n==2){ cout<<1<<endl; cout<<1<<" "<<1<<endl; } else{ cout<<2<<endl; for(int i = 2; i <= n+1; i++){ if(book[i]==0) cout<<1<<" "; else cout<<2<<" "; } cout<<endl; } return 0; }
-
思路:n^2做法是很好想的,显然会超时。怎么优化呢?类似与我们学过的打表求最大因子。我们可以存下所有数出现的次数,然后将所有他们的倍数加上他们的个数,最后记得减去一次自己重复加上的即可(这道题对时间复杂度要求挺高,暴力肯定过不了,哪怕是这串代码,也被卡cin)
AC代码:
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int maxn = 1e6 + 5; int a[maxn]; int b[maxn]; int c[maxn]; int main(void) { int n; cin >> n; int maxx = 0; for(int i = 1; i <= n; i++){ cin >> a[i]; b[a[i]]++; maxx = max(a[i],maxx); } for(int i = 1; i <= maxx; i++){ if(b[i]==0) continue; for(int j = i; j <= maxx; j += i){ c[j] += b[i]; } } for(int i = 1; i <= n; i++){ cout<<c[a[i]]-1<<endl; } return 0; }
-
前置知识:阶乘分解
思路:化简方程得
进一步得到
很多人会推到这被卡住了,我们两边同时加上 得
因式分解得到
令 , ,得到
我们要求(x,y)的对数,我们发现只要求出a的个数即可,因为 ,b和a的个数是一样的。怎么求a呢?我们发现a是 的一个因子,根据唯一分解定理,我们可以先把 分解掉可得
可得
那么根据唯一分解定理a的个数为
那么最后的答案即为:
AC代码:#include<bits/stdc++.h> using namespace std; typedef long long ll; const int mod = 1e9 + 7; const int maxn = 1e6+10; int num[maxn]; int cnt,prime[maxn]; bool vis[maxn]; void Init(int n){ for(int i = 2; i <= n; i++){ if(!vis[i]) prime[++cnt] = i; for(int j = 1; j <= cnt &&i*prime[j]<=n;j++){ vis[i*prime[j]] = 1; if(i%prime[j] == 0) break; } } } int main(void){ int n; cin >> n; Init(n); for(int i = 1; i <= n; i++){ int tmp = i; for(int j = 1; j <= cnt&&prime[j]*prime[j] <= tmp; j++){ if(tmp%prime[j]==0){ int ct = 0; while(tmp%prime[j] == 0){ tmp /= prime[j]; ct++; } num[prime[j]] += ct; } } if(tmp>1) num[tmp]++; } ll ans = 1; for(int i = 1; i <= cnt; i++) ans = (ans*(2*num[prime[i]]+1))%mod; cout<<ans<<endl; return 0; }
-
思路:显然,不可能直接去筛 2147483647 以内的素数;
由于任何一个合数n必定包含一个不超过 的质因子,
那么,我们不妨先用欧拉筛法筛出 [0,46341]区间内的素数(46341≈√2147483647);
然后对于每个【L,R】区间,用筛出来的质数再去标记【L,R】内的合数,剩下来的就是质数了。
细节之处,自己好好揣摩代码。
AC代码:
#include<bits/stdc++.h> using namespace std; const int maxn = 1e6+10; bool book[maxn]; bool vis[maxn]; int a[maxn]; typedef long long ll; ll l,r; void Init() { memset(book,0,sizeof(book)); memset(vis,0,sizeof(vis)); for(ll i = 2; i*i <= r; i++) { if(vis[i]==0) { for(ll j = i+i; j*j <= r; j += i) vis[j] = 1; for(ll j = max(2ll,(l+i-1)/i)*i; j <= r; j += i)////(L-1+i/i)得到最接近L的i的倍数 book[j-l] = 1;////偏移量,因为单纯j会导致数组越界,把范围弄到0到len上 } } } int main(void) { while(cin>>l>>r) { if(l==1) l++; Init(); int cnt = 0; int flag = 0; for(int i = 0; i <= r-l; i++) { if(book[i]==0) { flag = 1; a[cnt++] = i+l; } } if(flag==0||cnt==1) cout<<"There are no adjacent primes."<<endl; else { ll minx = 0x3f3f3f3f; ll maxx = -0x3f3f3f3f; ll pos1,pos2; ll q1,q2; for(int i = 1; i < cnt; i++) { ll t = a[i]-a[i-1]; if(t<minx) { minx = t; pos1 = a[i]; pos2 = a[i-1]; } if(t > maxx) { maxx = t; q1 = a[i]; q2 = a[i-1]; } } cout<<pos2<<","<<pos1<<" are closest, " <<q2<<","<<q1<<" are most distant."<<endl; } } return 0; }
-
PS:这是一道很好的模拟
题意:你正在玩你最喜欢的一款游戏,现在你闯到了最后一关,要和大Boss一决高下。
Boss有两个属性:生命值max和每秒钟回复的生命值reg。
你手上有N个卷轴,每个卷轴也有两个属性:卷轴使用时Boss的最大血量百分比 (如果Boss的血量百分比大于 ,则无法使用这个卷轴)和卷轴每秒钟造成的伤害 。卷轴是一次性的,但是它的效果会持续到游戏结束。
每一秒钟战斗的顺序是:Boss先受到所有卷轴造成的伤害,然后回复reg点生命值(当然,Boss的血量不能超过max),然后你使用可以使用的一个卷轴。
当某一秒Boss受到伤害并回复血量之后血量小于等于0时,你就赢了。
现在请你回答:你是否能够赢这一局游戏?如果可以,求出最短用时、每一个卷轴是否被使用和使用过的卷轴被使用的时间。
注意:在获胜的那一秒不能使用卷轴
思路:模拟。。。
AC代码:
#include <iostream> #include <stdio.h> #include <string.h> #include <algorithm> #include <cmath> using namespace std; int n,x,y,t[1010],id[1010],vis[1010]; struct node{ int id, p, d; }a[1010]; bool cmp1(node a,node b){return a.d>b.d;} bool cmp2(node a,node b){return a.id<b.id;} int main() { scanf("%d%d%d",&n,&x,&y); for(int i=1;i<=n;i++){ scanf("%d%d",&a[i].p,&a[i].d); a[i].id = i; } sort(a+1,a+1+n,cmp1); int now = x, d = 0, be = 0, cnt = 0; for(int i=0; ; i++){ now -= d; now += y; now = min(now, x); if(now<=0){ printf("YES\n%d %d\n",i,cnt); for(int j=0;j<cnt;j++) printf("%d %d\n",t[j],id[j]); return 0; } for(int j=1;j<=n;j++){ if(vis[j]||a[j].p*x<now*100) continue; vis[j] = 1; d += a[j].d; t[cnt] = i; id[cnt++] = a[j].id; break; } if(be==d&&d<=y) break; be = d; } printf("NO\n"); return 0; }
『日常训练』2020WFU个人积分赛第三场
猜你喜欢
转载自blog.csdn.net/wxd1233/article/details/105591362
今日推荐
周排行