牛客周赛47

A:直接判断一个元素是否有三个一个是否有两个

#include<bits/stdc++.h>
using namespace std;
int a[110];
int main()
{
    int n=5;
    while(n--)
    {
        int x;cin>>x;
        a[x]++;
    }
    sort(a,a+110);
    if(a[109]==3&&a[108]==2)puts("YES");
    else puts("NO");
    return 0;
}

B:用map即可:map是STL的一个关联容器,它提供一对一的hash

map详情点击这

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N = 2e5+10;
int a[N];
signed main()
{
	int n;
	cin>>n;
	int t=n;
	while(n--)
	{
		map<char,int>h;
		string s;cin>>s;
		for(int i=0;i<s.size();i++)
			h[s[i]]++;
		for(char i='a';i<='z';i++)
		{
			if(h[i]>=1)
			{
				a[i]++;
			}
		}
	}
	for(char i='a';i<='z';i++)
	{
		if(a[i]==t)
		{
			cout<<i;
            break;
		}
	}
}

C

#include<bits/stdc++.h>
#define LL long long
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define rep(i,a,n) for(int i = a; i <= n; ++i)
#define rrep(i,n,a) for(int i = n; i >= a; --i)
#define lowbit(x) x&-x
#define int long long
using namespace std;
const int N=2e5+10,mod=1e9+7,MOD=998244353;
int a[N];
void solve()
{	
    int n;
    cin>>n;
    int sum=0;
    rep(i,1,n) cin>>a[i],sum+=a[i];
    bool ok=0;
    if(n==2&&a[1]==a[2])//特判两个相同的情况
    {
        cout<<0<<endl;
        return;
    }
    rep(i,1,n)
    {
        if(a[i]>=sum-a[i]) ok=1;
    }
    if(ok)//如果一个数大于其他所有数之和,那么只有它可以留下 
    {
        cout<<1<<endl;
        return;
    }
    if(sum&1)//然后是奇数的情况,奇数一定会留一个数,
        //所以每种数字都有机会留下
        cout<<n<<endl;
    else//偶数的话,只可能留下两个相同的,所以值要大于2
    {
        int cnt=0;
        rep(i,1,n) if(a[i]>1) cnt++;
        cout<<cnt<<endl;
    }
}
signed main()
{
	IOS;
    int t=1;
    //cin>>t;
    while(t--) solve();
}	

D

#include<bits/stdc++.h>
#define x first
#define y second
#define LL long long
#define PII pair<int, int>
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define INF 0x3f3f3f3f
#define rep(i,a,n) for(int i = a; i <= n; ++i)
#define rrep(i,n,a) for(int i = n; i >= a; --i)
#define yes cout<<"YES\n"
#define no cout<<"NO\n"
#define mm(x) memset(x,0,sizeof(x))
#define all(x) x.begin(), x.end()
#define lowbit(x) x&-x
#define int long long
using namespace std;
const int N=2e5+10,mod=1e9+7,MOD=998244353;
int a[N];
void solve()
{	
    int n;
    cin>>n;
    auto check=[&](int x)
    {
        int s=x;
        s-=(x/3);//减去3的倍数
        s-=(x-3)/10;//减去最后一位为3
        s+=(x-3)/10/3;//可能减重复的,加上既是3的倍数尾数也是3
        return s;
    };
    int l=0,r=1e15;
    while(l<r)//二分找前n个数有多少个好数
    {
        int mid=(l+r)>>1;
        if(check(mid)>=n) r=mid;
        else l=mid+1;
    }
    cout<<l<<endl; 
}
signed main()
{
	IOS;
    int t=1;
    cin>>t;
    while(t--) solve();
}	

E:关于x轴对称的数字个数 + 关于y轴对称的数字个数 - 同时关于x轴和y轴对称

关于x轴,可以填 0 1 3 8,y轴0 2 5 8,同时关于x轴和y轴,只能填0 8

奇数时,纵轴所在的元素只能选择0,8

#include<bits/stdc++.h>
using namespace std;
#define int long long
const int mod=1e9+7;
int n;
int qmi(int a, int b)
{
    int res = 1;
    while(b)
    {
        if(b & 1) res = res * a % mod;
        b >>= 1;
        a = a * a % mod;
    }
    return res;
}
signed main()
{
    cin>>n;
    int m=n/2;
    if(n%2==0)
    {
        int x=qmi(4,n);//x对称0138
        int y=qmi(4,m);//y对称0258
        int xy=qmi(2,m);//xy对称08
        cout<<(x+y-xy+mod)%mod;
        return 0;
    }
    else
    {/*n为奇数时,纵轴所在的元素只能选择0,8,
        纵轴左边的元素只能选择0,8,2,5,当左边选择0,8时
        右边对应选择0,8,左边选择2,5时,右边对应选择5,2,
        所以n为奇数时纵轴对称的情况种数为:((pow(4, n / 2) * 2)
        。n为偶数时,纵轴左边的元素和右边元素的选择情况和n为奇数时一致,
        只是不需要考虑纵轴所在的元素的选择情况,所以n为偶数时纵轴对称的
        情况种数为:(pow(4, n / 2) * 1),综合讨论得到纵轴对称的种数为
        :((pow(4, n / 2) * (n % 2 == 1 ? 2 : 1))。*/
        int x=qmi(4,n);
        int y=qmi(4,m)*2;
        int xy=qmi(2,((n+1)/2));
        cout<<(x+y-xy+mod)%mod;
        return 0;
    }
}

F:dijkstra要小根堆实现,array的用法

#include <bits/stdc++.h>
using namespace std;
const int N=110;
#define endl '\n'
#define int long long 
int n,m;
int d[N][N],c[N];
string s[N];
int dx[4]={-1,0,1,0},dy[4]={0,1,0,-1};
void solve()
{
	cin>>n>>m;
	for(int i=0;i<n;i++) cin>>s[i];
	for(int i=0;i<m;i++) cin>>c[i];
	priority_queue<array<int,3>> q;//默认大根堆
	memset(d,0x3f,sizeof d);
	d[0][0]=0;//到每个点的最小代价
	q.push({0,0,0});
	while(q.size())
	{
		auto t=q.top();q.pop();
		int w=t[0],x=t[1],y=t[2];
		w=-w;//为了变成小根堆
		for(int i=0;i<4;i++)
		{
			int nx=x+dx[i],ny=dy[i]+y;
			if(nx<0||ny<0||nx>=n||ny>=m) continue;
			if(s[nx][ny]=='.')
			{
				if(d[nx][ny]>w) 
				{
					d[nx][ny]=w;q.push({-w,nx,ny});
				}
			}
			else//加点
			{
				for(int xx=0;xx<n;xx++)
				{
					if(d[xx][ny]>c[ny]+w)
					{
						d[xx][ny]=c[ny]+w;
						q.push({-d[xx][ny],xx,ny});
					}
				}
			}
		}
	}
    /*for(int i=0;i<n;i++)
    {
        for(int j=0;j<m;j++)
        {
            cout<<d[i][j]<<" ";
        }
        cout<<endl;
    }*/  
	cout<<d[n-1][m-1];
}
signed main()
{
	int T=1;//cin>>T;
	while(T--) solve();
	return 0;
 } 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值