智算之道高校组复赛

参考链接、

比赛当天直接睡过头了。三点半起来的。晕晕乎乎开始写。

A

暴力100-999

B

把起点和终点丢进去,直接dp

/*
    author:revolIA
    submit:;
*/
#include<bits/stdc++.h>
#pragma GCC optimize(3)
using namespace std;
typedef long long ll;
const int maxn = 2e3+7;
int cnt;
pair<int,int> point[maxn];
int n,w1,w2,k;
ll dp[maxn];
ll getAns(pair<int,int> s,pair<int,int> t){
    return 1LL*(t.first-s.first+t.second-s.second)*w1;
}
int main(){
    scanf("%d%d%d%d",&n,&k,&w1,&w2);
    point[cnt++] = {0,0};
    while(k--){
        scanf("%d%d",&point[cnt].first,&point[cnt].second);
        if(w1*2LL>w2){
            cnt++;
        }
    }
    point[cnt] = {n,n};
    sort(point+1,point+cnt);
    memset(dp,0,sizeof dp);
    for(int i=1;i<=cnt;i++)dp[i] = getAns({0,0},point[i]);
    for(int i=1;i<=cnt;i++){
        for(int j=1;j<=cnt;j++){
            if(point[i].first<point[j].first&&point[i].second<point[j].second)
            dp[j] = min(dp[i]+
                        min(
                        getAns({point[i].first+1,point[i].second+1},point[j])+w2,
                        getAns(point[i],point[j])
                        ),dp[j]
                    );
        }
    }
    printf("%lld\n",dp[cnt]);
    return 0;
}

C

不会做,感觉是个二进制找规律,但是懒得找,直接写了暴力莽了40分后开始搞d,然后被内存搞炸了心态。

赛后,果然二进制找规律。贴一个滑稽大佬的代码

/*
    author:revolIA
    submit:;
*/
#include<bits/stdc++.h>
#pragma GCC optimize(3)
using namespace std;
typedef long long ll;
const int maxn = 1e5+7;
int N;
unsigned long long k;
int main(){
    scanf("%llu%d",&k,&N);
    if(k<N){
        int n = k+1;
        printf("%d %d\n",n,(n-2)*2+1);
        printf("%d %d\n",1,n);
        for(int i=2;i<n;i++){
            printf("%d %d\n%d %d\n",1,i,i,n);
        }
    }else{
        int p = -1,m = 0;
        for(int i=63;~i;i--){
            if(k>>i&1){
                m++;
                if(p == -1)p = i;
            }
            if(~p){
                m += i+1;
            }
        }
        int n = p+3;
        printf("%d %d\n",n,m);;
        for(int i=0;i<=p;i++){
            for(int j=-1;j<i;j++){
                printf("%d %d\n",j+2,i+2);
            }
        }
        for(int i=p;~i;i--){
            if(k>>i&1){
                printf("%d %d\n",i+2,n);
            }
        }
    }
    return 0;
}

D

炸内存了,草。半年没打比赛脑壳都僵住了。

赛后看滑稽大佬题解。忘记了素数数组可以继续精简一下。

/*
    author:revolIA
    submit:;
*/
#include<bits/stdc++.h>
#pragma GCC optimize(3)
using namespace std;
typedef long long ll;
const int maxn = 8e7+7;
const long long mod = 1LL<<32;
bool vis[maxn];
int prim[maxn/10],cnt;
int ans[maxn];
ll n,a,b;
void sprim(){
    for(int i=2;i<=n;i++){
        if(!vis[i])prim[++cnt] = i,ans[i] = i;
        for(int j=1;j<=cnt&&1LL*i*prim[j]<=n;j++){
            vis[i*prim[j]] = 1;
            if(i%prim[j] == 0){
                if(ans[i]){
                    ans[i*prim[j]] = prim[j];
                }
                break;
            }
        }
    }
}
int main(){
    scanf("%lld%lld%lld",&n,&a,&b);
    if(n == 1)return 0*printf("%d\n",a);
    sprim();
    for(int i=2;i<=n;i++){
        if(!ans[i])continue;
        a = (a*ans[i]%mod+b)%mod;
    }
    printf("%lld\n",a);
    return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值