当前位置: 首页 > news >正文

icpc2023西安邀请赛部分题解(GJAHE)

题目链接:The 2023 ICPC Xi'an Invitational Programming Contest - 比赛主页 - 比赛 - QOJ.ac

G. Permutation

思路

纯签到没啥好说的

代码

void solve(){
    int n;
    cin>>n;
    for(int i=1;i<=n;i++){
        cout<<i<<" ";
    }
}

J. Target

思路

可以对a进行的操作:1.a/2 2.a/2+0.5 对于0<=a<=1我们发现操作1能让a变小,操作2能让a变大

我们可以尝试先把a变成0,再把a变成b,暴力打表发现第一步最大不会超过15,第二步不会超过20,直接暴力搜索即可

代码

#include<bits/stdc++.h>
using namespace std;

#define vcoistnt ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL); 
#define int long long
#define vi vector<int>
#define vb vector<bool>
typedef pair<int,int> pll;

const int N=2e5+10;
const int inf=1e18;
const int mod=998244353;
const double eps=1e-4;

void solve(){
    vector<int> ans;
    double a,b;
    cin>>a>>b;
    while(a>eps){
        a/=2;
        ans.push_back(1);
    }
    vector<int> t(50,0);
    bool f=false;
    auto dfs=[&](auto self,double x,int ct)->void{

        if(f||ct>20) return;
        if(abs(x-b)<=eps){
            for(int i=0;i<ct;i++){
                cout<<t[i];
            }
            f=true;
            return;
        }
        t[ct]=1;
        self(self,(x*1.0)/2,ct+1);
        t[ct]=2;
        self(self,(x*1.0)/2+0.5,ct+1);

    };
    for(int i:ans){
        cout<<i;
    }
    dfs(dfs,0,0);
    
}
signed main() {
    vcoistnt
    cout<<fixed<<setprecision(2);
    int _=1;
    // cin>>_;
    while(_--) solve();
    return 0;
}

A. Alice and Bob

思路

此题思路模拟样例就能得出

当以p[1]为开头的时候,p[1]长度内p[1]后面的数必须大于p[1]才能使得Bob获胜

那么这题就变成了组合数学的问题,

将所有开头的情况枚举,答案相加即可

代码

#include<bits/stdc++.h>
using namespace std;

#define vcoistnt ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL); 
#define int long long
#define vi vector<int>
#define vb vector<bool>
typedef pair<int,int> pll;

const int N=1e7+10;
const int inf=1e18;
const int mod=998244353;


int fac[N];
int inv[N];

int ksm(int a,int b){
    int ans=1;
    while(b){
        if(b&1){
            ans=(ans*a)%mod;
        }
        a=((a%mod)*(a%mod))%mod;
        b>>=1;
    }
    return ans;
}

int C(int n,int m){
    if(m>n) return 0;
    return fac[n] * inv[m]%mod * inv[n-m]%mod;
}

void init(){
    fac[0]=1;
    inv[0]=1;
    for(int i=1;i<N;i++){
        fac[i]=(fac[i-1]*i)%mod;
    }
    inv[N-1]=ksm(fac[N-1],mod-2);
    for(int i=N-2;i>=1;i--){
        inv[i]=inv[i+1]*(i+1)%mod;
    }
}

int A(int n,int m){
    if(m>n || m<0 || n<0){
        return 0;
    }
    return fac[n]*inv[n-m]%mod;
}

void solve(){
    int n;cin>>n;
    int ans=0;
    
    for(int i=1;i<=n;i++){
        ans=(ans+A(n-i,i-1)*A(n-i,n-i))%mod;
    }

    cout<<ans<<"\n";
}
signed main() {
    vcoistnt
    cout<<fixed<<setprecision(2);
    int _=1;
    init();
    // cin>>_;
    while(_--) solve();
    return 0;
}

H. Spin the Wheel

思路

严格证明不是很会,只能说这题做出来全凭经验找规律猜结论,多观察几个例子我们发现,当我们在旋转之后加我们不会影响相邻两数之间差值%n的相等性,如果差值%n不相等直接输出-1

但相邻两数之间的差值%n是可以改变的,我们发现我们每进行一次操作便能使差值+1,然后我们贪心的求最小值,那么答案便是差值%n,如果a[0]!=0便需要再操作1次

特殊如果所有值都相等时特判一下

代码

#include<bits/stdc++.h>
using namespace std;

#define vcoistnt ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL); 
#define int long long
#define vi vector<int>
#define vb vector<bool>
typedef pair<int,int> pll;

const int N=2e5+10;
const int inf=1e18;
const int mod=998244353;

void solve(){
    int n;
    cin>>n;
    vi a(n+10);
    int isame=0;
    bool f=false;
    for(int i=0;i<n;i++){
        cin>>a[i];

        if(i==0) isame=a[i];
        else{
            if(a[i]!=isame) f=true;
        }

    }
    if(!f){
        if(isame==0) cout<<"0\n";
        else cout<<n+1<<"\n";
        return;
    }
    int x=(a[1]-a[0]+n)%n;

    int ans=x+(a[0]!=0);
    for(int i=0;i<n;i++){
        if( (a[(i+1)%n] - a[i%n]+n) %n != x) ans=-1;
    }
    cout<<ans<<"\n";

}
signed main() {
    vcoistnt
    cout<<fixed<<setprecision(2);
    int _=1;
    // cin>>_;
    while(_--) solve();
    return 0;
}

E. Merge the Rectangles

思路

刚开始的思路便是我们遇到一条能合并的边便将其合并,之后发现这并不可行

观察例子我们发现对于一个合法的图像,即如果一个矩形最终能合并的话那么这个矩形内部必然存在至少一条能够贯穿此矩形的线,这条线能够将此矩形分为两个小矩形

那么我们递归暴力搜索一下就行,因为是01那么我们可以用前缀和来判断这条线是否贯穿

代码

#include<bits/stdc++.h>
using namespace std;

#define vcoistnt ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL); 
#define int long long
#define vi vector<int>
#define vb vector<bool>
typedef pair<int,int> pll;

const int N=2e5+10;
const int inf=1e18;
const int mod=998244353;

vector<vi> x(1505,vi(1505));
vector<vi> y(1505,vi(1505));

bool dfs(int x1,int y1,int x2,int y2){
    int sum=0;
    for(int i=x1+1;i<x2;i++){
        if(y[i][y2-1]-y[i][y1-1]==y2-y1){
            return dfs(x1,y1,i,y2) && dfs(i,y1,x2,y2);
        }
        sum+=y[i][y2-1]-y[i][y1-1];
    }
    for(int i=y1+1;i<y2;i++){
        if(x[x2-1][i]-x[x1-1][i]==x2-x1){
            return dfs(x1,y1,x2,i)&&dfs(x1,i,x2,y2);
        }
        sum+=x[x2-1][i]-x[x1-1][i];
    }
    if(!sum) return true;
    return false;
}


void solve(){
    int n,m;
    cin>>n>>m;
    for(int i=2;i<=n;i++){
        for(int j=1;j<=m;j++){
            char c;cin>>c;
            y[i][j]+=(c-'0');
            y[i][j]+=y[i][j-1];
        }
    }
    for(int i=1;i<=n;i++){
        for(int j=2;j<=m;j++){
            char c;cin>>c;
            x[i][j]+=(c-'0');
            x[i][j]+=x[i-1][j];
        }
    }
    if(dfs(1,1,n+1,m+1)) cout<<"YES\n";
    else cout<<"NO\n";
}
signed main() {
    vcoistnt
    cout<<fixed<<setprecision(2);
    int _=1;
    // cin>>_;
    while(_--) solve();
    return 0;
}

相关文章:

  • Java数组
  • 第十五届蓝桥杯大赛软件赛省赛Python 大学 C 组:6.挖矿
  • 微信小程序学习实录12:掌握大数据量轨迹展示的MySQL结构设计
  • 关于使用HAL_ADC_Start函数时为什么要放在while里的解释
  • CSS语言的网络编程
  • 使用私有知识库取消歧义思考
  • 云轴科技ZStack CTO王为@中国GenAI大会:AI原生实践重构AI Infra新范式
  • 简洁的 PlantUML 入门教程
  • indexedDB前端数据库存储使用
  • d202546
  • Java项目集成大模型(通译千问)
  • Python星球日记 - 第3天:运算符与表达式
  • 内存与显存:从同根生到殊途异路的科技演进
  • 机器学习新范式:Kubernetes + Kubeflow,解锁模型训练与部署的高效密码
  • Word 页眉设置(不同章节不同页眉)
  • 迭代器介绍与使用(四十一)
  • java 正则表达式优化
  • 使用SPSS进行链式中介模型分析
  • ansible可视化自动化平台-semaphore
  • 脑电学习笔记
  • php做网站商城系统怎么样/长春seo优化企业网络跃升
  • 河北省建设工程安全生产监督管理网站/百度一下你就知道百度一下
  • 工厂 电商网站建设/电脑优化软件推荐
  • 网站ar怎么做/蚁坊软件舆情监测系统
  • 那些论坛网站做的比较好/百度站长平台app
  • discuz做服务网站/b站不收费网站