题面:[ 传送门 ]
总的来说 这场比赛的难度比今年第一场和前几年的低 考的知识点并不多
A 求余
签到题
B 双阶乘
#include<bits/stdc++.h>
using namespace std;
#define ll long long
ll gcd(ll a,ll b){
return b==0?a:gcd(b,a%b);
}
int main(){
ll ans=1;
for(int i=1;i<=2021;i+=2){
ans*=i;
ans%=100000;
}
cout<<ans;
return 0;
}//59375
C 格点
#include<bits/stdc++.h>
using namespace std;
#define ll long long
ll gcd(ll a,ll b){
return b==0?a:gcd(b,a%b);
}
int main(){
ll ans=0;
for(int i=1;i<=2021;i++){
for(int j=1;j<=2021;j++){
if(i*j<=2021)ans++;
}
}
cout<<ans;
return 0;
}//15698
D 整数分解
记忆化搜索 + 动态规划
#include<bits/stdc++.h>
using namespace std;
#define ll long long
ll gcd(ll a,ll b){
return b==0?a:gcd(b,a%b);
}
ll ans=2021;
ll d[2025][15];
ll num[15];
ll dp(int v,int n){
// cout<<v<<' '<<n<<'\n';
if(n==1){
// for(int i=5;i>1;i--)cout<<num[i]<<' ';
// cout<<v<<'\n';
return d[v][n]=1;
}
if(~d[v][n])return d[v][n];
d[v][n]=0;
for(int i=1;i<=v-n+1;++i){
num[n]=i;
d[v][n]+=dp(v-i,n-1);
}
return d[v][n];
}
int main(){
memset(d,-1,sizeof(d));
cout<<dp(ans,5);
return 0;
}//691677274345
E 城邦
最小生成树 并查集 + 克鲁斯卡尔(Kruskal)算法
#include<bits/stdc++.h>
using namespace std;
#define ll long long
ll gcd(ll a,ll b){
return b==0?a:gcd(b,a%b);
}
ll mp[2025][2025];
struct node{
ll f,t,v;
node(int ff,int tt,ll vv):f(ff),t(tt),v(vv){
}
};
ll f(int i,int j){
ll cost=0;
while(i||j){
int ii=i%10;
int jj=j%10;
i/=10;
j/=10;
if(ii!=jj)cost+=ii+jj;
}
return cost;
}
vector<node>q;
inline bool cmp(node a,node b){
return a.v<b.v;
}
int fa[2025];
int findf(int idx){
return fa[idx]==idx?idx:fa[idx]=findf(fa[idx]);
}
ll c=0;
int main(){
for(int i=1;i<2021;i++){
for(int j=i+1;j<=2021;j++){
ll cost=f(i,j);
q.push_back(node(i,j,cost));
}
}
sort(q.begin(),q.end(),cmp);
for(int i=1;i<=2021;i++){
fa[i]=i;
}
for(int i=0,sz=q.size();i<sz;i++){
int ff=findf(q[i].f);
int ft=findf(q[i].t);
if(ff!=ft){
fa[ff]=ft;
findf(ft);
findf(ff);
c+=q[i].v;
}
}
cout<<c;
return 0;
}//4046
F 特殊年份
#include<bits/stdc++.h>
using namespace std;
#define ll long long
ll gcd(ll a,ll b){
return b==0?a:gcd(b,a%b);
}
ll cnt=0;
ll a;
bool f(int a){
int n[5];
for(int i=0;i<4;i++){
n[i]=a%10;
a/=10;
}
if(n[0]==n[2]+1&&n[1]==n[3])return true;
return false;
}
int main(){
for(int i=0;i<5;i++){
cin>>a;
if(f(a)){
++cnt;
// cout<<a<<'\n';
}
}
cout<<cnt;
return 0;
}
G 小平方
#include<bits/stdc++.h>
using namespace std;
#define ll long long
ll gcd(ll a,ll b){
return b==0?a:gcd(b,a%b);
}
ll n,mid,cnt=0;
int main(){
cin>>n;
if(n&1) mid=(n>>1)+1;
else mid=(n>>1);
for(ll i=1;i<n;i++){
if((i*i)%n<mid){
++cnt;
}
}
cout<<cnt;
return 0;
}
H 完全平方数
在 n \sqrt{n} n中找 n n n的质因子,对于 n n n奇数次的质因子补成偶数次(即 x x x包含一个该质因子),在 n \sqrt{n} n中没有找到质因子的数,即为质数,输出 n n n自身即可。
/*
* @Autor: CofDoria
* @Date: 2021-05-09 16:25:51
* @LastEditTime: 2021-05-09 16:28:14
*/
#include <bits/stdc++.h>
using namespace std;
#define ll long long
ll gcd(ll a, ll b) {
return b == 0 ? a : gcd(b, a % b); }
ll n, ans = 1, ok = 0;
int main() {
cin >> n;
ll len = sqrt(n) + 1;
for (ll q = 2; q <= min(n, len); ++q) {
ll cnt = 0;
while (n % q == 0) {
ok = 1;
n /= q;
++cnt;
}
if (cnt & 1) {
ans *= q;
}
}
if (!ok) ans = n;
cout << ans;
return 0;
}
I 负载均衡
模拟
任务的结束时间放进优先队列
#include<bits/stdc++.h>
using namespace std;
#define ll long long
ll gcd(ll a,ll b){
return b==0?a:gcd(b,a%b);
}
struct node{
ll t,cost;
bool operator < (const node &a)const{
return t>a.t;
}
node(ll tt,ll cc):t(tt),cost(cc){
}
};
struct com{
priority_queue<node>q;
ll idx,p,lev;
com(ll i=0,ll pp=0,ll l=0){
idx=i;
p=pp;
lev=l;
while(!q.empty()) q.pop();
}
}comp[200005];
ll n,m,v,a,c,d,b;
int main(){
ios::sync_with_stdio(false);
cin.tie(0),cout.tie(0);
cin>>n>>m;
for(int i=1;i<=n;++i){
cin>>v;
comp[i].idx=i;
comp[i].p=v;
comp[i].lev=v;
}
for(int _=0;_<m;++_){
cin>>a>>b>>c>>d;
while(!comp[b].q.empty()&&comp[b].q.top().t<=a){
comp[b].lev+=comp[b].q.top().cost;
comp[b].q.pop();
}
// cout<<comp[b].lev<<' ';
// if(!comp[b].q.empty())cout<<comp[b].q.top().t;
// cout<<" #\n";
if(comp[b].lev>=d){
comp[b].q.push(node(a+c,d));
comp[b].lev-=d;
cout<<comp[b].lev<<'\n';
}else{
// cout<<comp[b].lev<<'\n';
cout<<"-1\n";
}
}
return 0;
}
/*
2 6
5 5
1 1 5 3
2 2 2 6
3 1 2 3
4 1 6 1
5 1 3 3
6 1 3 4
*/
J 国际象棋
蒟蒻只会暴搜 能搜 6 6 5 的45%的点
队内巨巨lyk的状压DP解法可以跑全部点 (6 100 20 跑200ms以内)指路:[ 传送门 ]
#include<bits/stdc++.h>
using namespace std;
#define ll long long
ll gcd(ll a,ll b){
return b==0?a:gcd(b,a%b);
}
ll n,m,k;
bool ex[105][15];
ll ans=0;
int st[][2]={
{
2,1},{
-2,1},{
2,-1},{
-2,-1},{
1,2},{
-1,2},{
1,-2},{
-1,-2}};
void dfs(int x,int y,int d){
for(int i=0;i<8;++i){
int xx=x+st[i][0];
int yy=y+st[i][1];
if(xx>=0&&xx<m&&yy>=0&&yy<n){
if(ex[xx][yy])return ;
}
}
if(d>=k){
++ans;
if(ans==1000000007)ans=0;
return ;
}
ex[x][y]=true;
for(int i=x;i<m;++i){
for(int j=(i==x?y+1:0);j<n;++j){
if(!ex[i][j])dfs(i,j,d+1);
}
}
ex[x][y]=false;
return ;
}
int main(){
cin>>n>>m>>k;
memset(ex,false,sizeof(ex));
for(int i=0;i<m;++i){
for(int j=0;j<n;++j){
dfs(i,j,1);
}
}
cout<<ans;
return 0;
}