2023 蓝桥杯 A组 蒟蒻代码

        AC了 

        总的来说,比上次友善多了,这才是我熟悉的暴力杯。

        就做了3个满的,7道全骗(年轻人,来骗,来,偷袭!

1     幸运数    话不多说,马上开爆   机房电脑跑了几十秒才出答案

      就问你出没出答案吧

#include<iostream>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
typedef long long ll;
bool check(int x)
{
	vector<int> vec;
	while(x)
	{
		vec.push_back(x%10);
		x/=10;
	}
	int sz=vec.size();
	if(sz%2!=0)return false;
	int a=0,b=0;
	for(int i=0;i<sz/2;i++)a+=vec[i];
	for(int i=sz/2;i<sz;i++)b+=vec[i];
	return a==b;
}
//4430091
int main()
{
	int ans=0;
	cout<<"test:"<<check(22)<<" "<<check(22)<<'\n';
	for(int i=1;i<=100000000;i++)
	{
		if(check(i))ans++;
	}
	cout<<ans;
	return 0; 
}

2     胜利的方案数。现在想想好像做错了 ,,  寄,因为必须保证开始连续7次胜利的前一场输掉,应该是枚举到23-1=22 

#include<iostream>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
ll C(ll n,ll m)
{
	ll res=1;
	//for(ll i=n;i>=n-m+1;i--)res*=i;
	for(ll i=n;i>=n-m+1;i--)res*=i;
	for(ll i=1;i<=m;i++)res/=i;
	return res;
}
ll ksm(ll x,ll a)
{
	ll res=1;
	while(a)
	{
		if(a&1)res*=x;
		x*=x;
		a>>=1;
	}
	return res;
}
//4540385
int main()
{
	ll res=0;
//	cout<<C(0,0)<<" "<<C(1,0)<<'\n';
	for(ll i=0;i<=23;i++)
	{
		for(ll j=0;j<=min(9ll,i);j++)
		{
			res+=C(i,j);
		}
	}
	cout<<res;
	return 0; 
}

3     平方差     不知道满分做法, x=a^2-b^2=(a+b)(a-b),这启发我们因式分解x,若x能分为a0,a1。a0+a1 为偶数 则可以把 a0*a1表示为 上面平方差形式,因此可以算作一个贡献。时间复杂度 O(n^1.5)

#include<iostream>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
int l,r;
int ans;
int main()
{	
	scanf("%d%d",&l,&r);
	for(int i=l;i<=r;i++)
	{
		int x=i;
		bool flag=false;
		for(int j=1;j<=x/j;j++)
		{
			if(x%j==0)
			{
				int t=x/j;
				if((j+t)%2==0)
				{
					flag=true;
					break;
				}
			}
		}
		if(flag)ans++;
	}
	printf("%d",ans);
	return 0; 
}

4       反转字符串 , dp【i】【j】,表示   下标 i到 j  的子字符串 反转后 比原来大还是小还是相等。若i>j 则 表示空字符串 ,也即相等 。因此dp【i】【j】(i<j) 等于0

我们观察 dp[i][j]与dp【i+1】【j-1】的关系,不难发现可以O(1)完成转移,因此DP 

O(n方) 切了。

#include<iostream>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N=5e3+10;
char s[N];
int n;
int dp[N][N];//0 equal  1 elss than after reverse  -1 less than after reverse
ll ans;
int main()
{
	scanf("%s",s+1);
	n=strlen(s+1);
	dp[n][n]=0;
	for(int i=n-1;i>=1;i--)
	{
		for(int j=i;j<=n;j++)
		{
			int a=s[i]-'0',b=s[j]-'0';
			if(a>b)dp[i][j]=1;
			else if(b==a)
			{
				dp[i][j]=dp[i+1][j-1];
			}
			else dp[i][j]=-1;			
		}
	}
	for(int i=1;i<=n;i++)
	{
		for(int j=i+1;j<=n;j++)
		{
			if(dp[i][j]==1)ans++;
		}
	}
	printf("%lld",ans);
	return 0; 
}

5   颜色平衡树       不会,对每个节点dfs一遍, O(n方)偏分

#include<iostream>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<map>
using namespace std;
typedef long long ll;
const int N=2e5+10;
int head[N];
int color[N];
int n;
struct node{
	int to,nxt;
}edge[N];
int idx;
map<int,int> mp;
int ans;
void add(int from,int to)
{
	edge[idx].to=to;
	edge[idx].nxt=head[from];
	head[from]=idx++;
}
void dfs(int u)
{
	mp[color[u]]++;
	for(int i=head[u];~i;i=edge[i].nxt)
	{
		int v=edge[i].to;
		dfs(v);
	}
}
int main()
{
	memset(head,-1,sizeof head);
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
	{
		int fa;
		scanf("%d%d",&color[i],&fa);
		if(fa!=0)add(fa,i);	
	}
	for(int i=1;i<=n;i++)
	{
		mp.clear();
		dfs(i);
		int cm=(*mp.begin()).second;
		bool flag=true;
		for(map<int,int>::iterator i=mp.begin();i!=mp.end();i++)
		{
			if((*i).second!=cm)
			{
				flag=false;
				break;
			}
		}
		if(flag)ans++;
	}
	printf("%d",ans);		
	return 0; 
}

6    

        两层二进制枚举 很蠢 的骗了30%分  明明 可以写3^n 的  太蠢了

7     数字电路好像叫这名r

     Floyd  骗 30%

#include<iostream>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<map>
using namespace std;
typedef long long ll;
const int N=5e3+10;
const int INF=0x3f3f3f3f;
int n,m,q;
int dist[N][N];
int main()
{
	scanf("%d%d%d",&n,&m,&q);
	memset(dist,0x3f,sizeof dist);
//	for(int i=0;i<=n;i++)dist[i][i]=0;
	for(int i=1;i<=m;i++)
	{
		int a,b,c;
		scanf("%d%d%d",&a,&b,&c);
		int temp=dist[a][b];
		if(temp!=INF)dist[a][b]=dist[b][a]=max(c,temp);
		else dist[a][b]=dist[b][a]=c;
	}
	for(int k=1;k<=n;k++)
	{
		for(int i=1;i<=n;i++)
		{
			for(int j=1;j<=n;j++)
			{
				//dist[a][b]=max(dist[a][b],min(dist[a][k],dist[k][b]));
				int temp=min(dist[i][k],dist[k][j]);
				if(dist[i][k]==INF||dist[k][j]==INF)temp=INF;
				if(dist[i][j]==INF)dist[i][j]=temp;
				else {
					if(temp!=INF)dist[i][j]=max(dist[i][j],temp);
				}
			}
		}
	}
//	for(int i=1;i<=n;i++)
//	{
//		for(int j=1;j<=n;j++)cout<<dist[i][j]<<" ";
//		cout<<'\n';
//	}
	while(q--)
	{
		int a,b;
		scanf("%d%d",&a,&b);
		if(dist[a][b]!=INF)printf("%d\n",dist[a][b]);
		else puts("-1");
	}
	return 0; 
}

8    异或和      前缀和 O(n方) 骗60%        正解 舍友说用二进制拆分  O(30n)

#include<iostream>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N=1e5+10;
ll a[N];
ll d[N];
int n;
ll ans;
int main()
{	
	scanf("%d",&n);
	for(int i=1;i<=n;i++)cin>>a[i];
	for(int i=1;i<=n;i++)
	{
		d[i]=a[i];
		d[i]^=d[i-1];
	}
	for(int i=1;i<=n;i++)
	{
		for(int j=i;j<=n;j++)
		{
			ans+=(d[j]^d[i-1]);
		}
	}
	printf("%lld",ans);
	return 0; 
}

9      很想数独的一道题        O(2^nm)暴力dfs开骗 

#include<iostream>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cctype>
using namespace std;
typedef long long ll;
const int N=15;
int n,m;
char g[N][N];
bool flag=false;
int dx[]={-1,-1,-1,0,0,1,1,1,0};
int dy[]={1,0,-1,1,-1,1,0,-1,0};
int nums[N][N];
inline bool check()
{
	for(int i=0;i<n;i++)
	{
		for(int j=0;j<m;j++)
		{
			if(g[i][j]=='_')continue;
			else
			{
				int target=g[i][j]-'0';
				int tot=0;
				for(int k=0;k<9;k++)
				{
					int a=i+dx[k],b=j+dy[k];
					if(a<0||a>=n||b<0||b>=m)continue;
					if(nums[a][b]==1)tot++;
				}
				if(tot!=target)return false;
			}
		}
	}
	return true;
}
void dfs(int a,int b)
{
	if(flag)return ;
	if(a==n)
	{
		if(check())
		{
			for(int i=0;i<n;i++)
			{
				for(int j=0;j<m;j++)printf("%d",nums[i][j]);
				puts("");
			}
			flag=true;
		}
		return ;
	}
	if(b==n){
		dfs(a+1,0);
		return ;
	}
	nums[a][b]=1;
	dfs(a,b+1);
	nums[a][b]=0;
	dfs(a,b+1);
	return ;
}
int main()
{
	scanf("%d%d",&n,&m);
	for(int i=0;i<n;i++)scanf("%s",g[i]);
	dfs(0,0);
	return 0; 
}

10           抛硬币        O(nlogn)   。 假设每个银币被翻转了 n次,因此  除了第一枚硬币,其他硬币的翻转次数应该为偶数。 我们从前考虑每一个硬币 ,第一个硬币一定要翻转一次,因此后面每个硬币 都会被翻转一次,我们从前往后考虑每个硬币 ,类似埃氏筛法的就能 暴力骗30%分 (前提代码没错  QAQ

#include<iostream>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N=5e6+10;
int n;
int cnt[N];
ll ans;
// o(nlogn)
int main()
{
	scanf("%d",&n);
	ans=1;
	for(int i=2;i<=n;i++)
	{
		if(cnt[i]%2==0){
			ans++;
			for(int j=i*2;j<=n;j+=i)cnt[j]++;
		}
	}
	printf("%lld",ans);
	return 0; 
}

没进过决赛  希望满足一次 TNT

-------------------更新----------------

省一          舒服了

  • 5
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 10
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值