8.13做题总结

SNCPC2024 vp

按照自认为的难度顺序排序

F题.P10696 [SNCPC2024] 写都写了,交一发吧

找最大值

#include<bits/stdc++.h>
using namespace std;
int main(){
	ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
	int t;
	cin>>t;
	while(t--){
		int n;
		cin>>n;
		long long mx=0;
		long long cm=0;
		for(int i =1;i<=n;i++){
			long long temp;
			cin>>temp;
			if(temp>=mx){
				cm=mx;
				mx=temp;
			}
	}
	long long ans=mx&mx;
		cout<<ans<<endl;
	}
	return 0;
	
}

 P10691 [SNCPC2024] chmod模拟题

输入三个三位数 每一位的二进制前三位的0或者1决定输出的结果

#include<bits/stdc++.h>
using namespace std;
int main(){
    int t;
    cin>>t;
    while(t--){
        string temp;
        cin>>temp;
        int s[3];
        s[0]=(int)temp[0]-48;
        s[1]=(int)temp[1]-48;
        s[2]=(int)temp[2]-48;
        char ans[9];
        if(s[0]%2&&1){
            ans[2]='x';
            s[0]/=2;
        }
        else {
        ans[2]='-';
        s[0]/=2;
    }
//            cout<<s[0]<<endl;
    if(s[0]%2&&1){
            ans[1]='w';
            s[0]/=2;;
        }
        else {
        ans[1]='-';
        s[0]/=2;
    }
//            cout<<s[0]<<endl;
        if(s[0]&&1){
            ans[0]='r';
            s[0]/=2;
        }
        else {
        ans[0]='-';
        s[0]/=2;
    }
//        cout<<s[0]<<endl;
    if(s[1]%2&&1){
            ans[5]='x';
            s[1]/=2;
        }
        else {
        ans[5]='-';
        s[1]/=2;
    }
    if(s[1]%2&&1){
            ans[4]='w';
            s[1]/=2;
        }
        else {
        ans[4]='-';
        s[1]/=2;
    }
        if(s[1]%2&&1){
            ans[3]='r';
            s[1]/=2;
        }
        else {
        ans[3]='-';
        s[1]/=2;
    }
//    
    if(s[2]%2&&1){
            ans[8]='x';
            s[2]/=2;
        }
        else {
        ans[8]='-';
        s[2]/=2;
    }
    if(s[2]%2&&1){
            ans[7]='w';
            s[2]/=2;
        }
        else {
        ans[7]='-';
        s[2]/=2;
    }
        if(s[2]%2&&1){
            ans[6]='r';
            s[2]/=2;
        }
        else {
        ans[6]='-';
        s[2]/=2;
    }
        
    for(int i = 0;i<=8;i++){
        cout<<ans[i];
    }
    cout<<endl;
        
        
    }
    return 0;
    
} 


丑陋的暴力 可以写一个循环

B题 P10692 [SNCPC2024] 表达式矩阵        

模拟+打表+贪心       

首先外层为1 内部全部填入*

当一行或者一列为11*11的情况将*改为+

一行或者一列最多只能放一个+

#include<bits/stdc++.h>
using namespace std;
int main(){
int n,m;
cin>>n>>m;
char mp[n+5][m+5];
memset(mp,'1',sizeof(mp));
if((m-2)%2==0||(n-2)%2==0){
for(int i = 2;i<=n-1;i+=2){
    if(m%2==1||n%2==1){
    for(int j = 2;j<=m-1;j+=2){
        mp[i][j]='*';
        if(i+1<=n-1&&j+1<=m-1)mp[i+1][j+1]='+';

        if(n>6||m>6){
            if(i+1<=n-3&&j+1<=m-1&&n>=m){
            mp[i+1][j+1]='*';
        if(m==5&&i+1<=n-3&&j+1<=m-1&&n>=m) mp[i+1][j+1]='+';
        }
            else if(i+1<=n-1&&j+1<=m-3&&m>n){
            mp[i+1][j+1]='*';
        if(n==5&&i+1<=n-1&&j+1<=m-3&&m>n)mp[i+1][j+1]='+';
        }
    }
}        
}
else{
    for(int j = 2;j<=m-1;j+=2){
        mp[i][j]='*';
        if(i+1<=n-1&&j+1<=m-1)mp[i+1][j+1]='*';
    }
    }
    }
    }
else {
    for(int i = 2;i<=n-1;i+=2){
    for(int j = 2;j<=m-1;j+=2){
        mp[i][j]='*';
        if(i+1<=n-1&&j+1<=m-1)mp[i+1][j+1]='+';
        if(n>=6||m>=6){ 
        if(n!=m){
            if(i+1<=n-3&&j+1<=m-1&&n>=m){
            mp[i+1][j+1]='*';
            if(m==5&&i+1<=n-3&&j+1<=m-1&&n>=m) mp[i+1][j+1]='+';
        }
        
        
    else if(i+1<=n-1&&j+1<=m-3&&m>n)mp[i+1][j+1]='*';
    if(n==5&&i+1<=n-1&&j+1<=m-3&&m>n)mp[i+1][j+1]='+';
        }
        else{
        if(i+1<=n-3&&j+1<=m-3){
            mp[i+1][j+1]='*';
        }
        mp[n-2][m-2]='*';
    }
    }
}
} 
}
if(n==8&&m==7){
mp[3][3]='+';
mp[5][5]='+';
mp[7][3]='*';
}
if(n==7&&m==8){
mp[3][3]='+';
mp[3][7]='*';
mp[5][5]='+';
}
if(n==9&&m==7){
    mp[7][5]='*';
    mp[5][5]='+';
    mp[3][3]='+';
}
if(n==7&&m==9){
    mp[5][5]='+';
    mp[5][7]='*';
    mp[3][3]='+';
}
if(n==9&&m==8){
    mp[3][3]='+';
    mp[7][3]='*';
    mp[7][5]='*';
    mp[5][5]='+';
}
if(n==8&&m==9){
    mp[3][3]='+';
    mp[3][7]='*';
    mp[5][7]='*';
    mp[5][5]='+';
    
}
if(n==9&&m==9){
    mp[7][3]='*';
        mp[3][3]='+';
        mp[3][7]='*';
        mp[5][5]='+';
        mp[5][7]='*';
        mp[7][7]='+';
        mp[7][5]='*';
}

for(int i = 1;i<=n;i++){
    for(int j = 1;j<=m;j++){
        cout<<mp[i][j];
    }
    cout<<endl;
}
    return 0;
    
}


M题P10703 [SNCPC2024] 窗花

思维题 

很显然 比如放一个点在(2,2)如果另一个点在他的上下左右即距离为1

他们重叠的面积为0.5 其他位置不重叠 只需一个个遍历 判断上下左右是否重叠将面积累加即可

#include<bits/stdc++.h>
#define int long long
using namespace std;
int n;
bool vis[101][101];
double ans;
main(){
	cin>>n;
	for(int i=1;i<=n;i++){
		int x,y;
		cin>>x>>y;
		if(vis[x][y]){
			continue;
		}vis[x][y]=true;
		ans+=2;
		if(vis[x-1][y])ans-=0.5;
		if(vis[x+1][y])ans-=0.5;
		if(vis[x][y-1])ans-=0.5;
		if(vis[x][y+1])ans-=0.5;
	}cout<<ans;
	return 0;
}

 题目说xy的范围为1到99,所以不会越界不用判断边界

G题P10697 [SNCPC2024] 消失的数字

给定n和x问从1到n中不包含x的数有多少,讨论当x等于9的时候包含的数为9进制的n个

当x不为9的时候 不妨当x为9 遍历每一位 当该位大于x 将他减少1;

代码如下

#include<bits/stdc++.h>
#define int long long
using namespace std;
bool vis[101][101];
double ans;
main(){

	int t;
	cin>>t;
	while(t--){
		long long n,x;
		cin>>n>>x;
		long long ans=0;
		int t=1;
		if(x==9){
			while(n>0){
				if(n%10==9){
					ans+=t*8;
				}
				else ans+=t*(n%10);
				n/=10;
				t*=9;
			}
		}
		else{
			while(n>0){
				if(n%10==x){
					ans+=t*8;
				}
				else if(n%10>x){
					ans+=t*(n%10-1);
				}
				else ans+=t*(n%10);
				n/=10;
				t*=9;
			}
		}
		cout<<ans+1<<endl;
	}
	
	return 0;
}

 C题P10693 [SNCPC2024] 换座位

给一个数组a[n]; ai可以取到2n,对于1-n每个i本来的位置是i想坐的位置是ai

求最大有多少能坐到自己想坐的位置

我们将i和ai连线

可以得到以下情况

1.连成一个带环的线(或者环)

例如1->2->3->2这种情况1只能在他本身的位置 2,3能坐到自己喜欢的位置成为一个环

2.连成树

例如 1->2->3->6

4->5->6;

形成一颗以6为顶点的树,这种情况显然求该顶点的最长边

实现思路,用拓扑排序求出环的长度 得到ans

然后求n+1到2*n(因为当i<=n时 他们才有喜欢的座位,所以顶点一定是>n的)

枚举这些点的最长边加到ans里面 得到答案

#include<bits/stdc++.h>
using namespace std;
const int N = 2*10e5;
vector<int> G[N];
vector<int> C[N];
int r[N];
	int a[N];
	bool h[N];
	long long ans=0;
	int n;
void tp(int n){
	int	st=1;
	while(st>0){
		st--;
	for(int i = 1;i<=n;i++){
			if(r[i]==0){
				r[i]--;
				st=1;
				r[G[i][0]]--;
			}
		}
	}
	for(int i = 1;i<=n;i++){
		if(r[i]==1){
			h[i]=true;
			ans++;
		}
	}
}
int mx;
int dp;
void dfs(int x){

	mx=max(dp,mx);
	if(C[x].size()>0){
		for(int i = 0;i<C[x].size();i++){
			dp++;
			dfs(C[x][i]);
			dp--;
		}
	}
	else return;
}

int main(){
	cin>>n;
	for(int i = 1;i<=n;i++){
		cin>>a[i];
		G[i].push_back(a[i]);
		C[a[i]].push_back(i);
		r[a[i]]++;
	}
	tp(n);
	for(int i = n+1;i<=2*n;i++){
			dp=0;
			mx=0;
			dfs(i);
			ans+=mx;
	}
	cout<<ans<<endl;

	return 0;
	
}

P10702 [SNCPC2024] 下棋

博弈+数学 lnc和ljj拿棋子

lnc是先手 一共有x个棋子,lnc选一个进制k,每次只能拿lnc数先拿完的赢

问最小的进制k是多少 lnc数为所有k禁止下所有数位的乘积为自身因子的数

例如

当 k=10k=10 时,y=(36)10y=(36)10​ 是 LNC 数,因为 (3×6)∣36

当 k=4k=4 时,y=(12)4 y=(12)4​ 是 LNC 数,因为转换成十进制后 (12)4=(6)10(12)4​=(6)10​,而 (1×2)∣6 

不妨设一个数字为32

他的二进制是100000

当lnc先手时 他的因数不能为0 所以他每一位都有数字

因为x末尾为0,不管他取多少的lnc数,棋子的末尾总会不为0,

此时对手取lnc数肯定会使得末尾为0,最后对手胜

因此 当取k进制 x末尾不为0时 lnc可以取一个数使得末尾为0 以此类推 他能获胜

只需枚举k判断x是否为k的倍数即可;

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

signed main(){
    ios::sync_with_stdio(false);
    cin.tie(0);cout.tie(0);
    int t; cin >> t;
    while(t--){
        int n; cin >> n;
        for(int x=2;;x++){
            if(n % x){
                cout << x << '\n';
                break;
            }
        }
    }    
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值