牛客多校第四场个人题解

N-​​​​​​Particle Arts

题意

已知 a , b 相撞变为 a&b 和 a|b 。

一个长度为n的数组,其中的数经历无数次相撞,将到达一个稳态,求在该稳态下的方差

思路

已知 a + b =(a&b)+ (a|b) 

eg. 3 + 4 = (3&4)+(3|4)= 0 + 7

可以发现前后和不变①

同时如果将这一过程转化为bitset格式

可以发现每一位的1的数量不会改变 

这个结论可以如下证明

0 + 0 = (0 & 0) + (0 | 0) = 0 + 0

1 + 0 = (1 & 0) + (1 | 0) = 0 + 1  

1 + 1 = (1 & 1) + (1 | 1) = 1 + 1

 对于任意一位,0和1的数量恒定不变,只会发生位置上的移动②

可以将相撞看作0和1在竖直方向上的相对移动

如果将初态中的"1”想象成俄罗斯方块中正在掉落的方块

那么稳态就是所有方块落地时的结果

代码

#include <bits/stdc++.h>
using namespace std;
#define js ios::sync_with_stdio(false);cin.tie(0); cout.tie(0)
#define debug system("pause")
#define ll long long

const int N=1e5+5;
int cnt[16];
ll v[N];

void solve(){
    ll n;cin>>n;       //涉及计算n*n*n 1e15
    ll ave=0;          //ave为na的平均值 ave=n*ai 3*1e9
    __int128 s=0;      //ll会爆

    for(int i=1;i<=n;i++){
      int x;cin>>x;
      ave += x;
      bitset<32> bs(x);
      for(int i=0;i<=15;i++) 
      if(bs[i]) cnt[i]++;    //统计每一位1的数量
    }

    for(int i=1;i<=n;i++){
        for(int j=0;j<=15;j++){
            if(cnt[j]){
            v[i] += 1<<j;
            cnt[j]--;
            }
        }
    }

    for(int i=1;i<=n;i++){
      v[i] *= n;
      s += (v[i] - ave) * (v[i] - ave);
    }

      __int128 n1 = n*n*n;
      __int128 gcd = __gcd(s,n1);
      ll ans1 = s/gcd;
      ll ans2 = n1/gcd;
      cout<<ans1<<"/"<<ans2;
}

int main(){
    js;
    int T = 1;
    while(T--) solve();
    debug;
}

K-NIO's Sword

代码


#include <bits/stdc++.h>
using namespace std;
#define js ios::sync_with_stdio(false);cin.tie(0); cout.tie(0)
#define debug system("pause")
#define ll long long
#define endl "\n"
const int MOD = 1e9 + 7;
const int INF = 0x3f3f3f3f;

int ws(int n){
    int ans=0;
    while(n){ n/=10;;ans++;}
    return ans;
}

int main(){
    int n;cin>>n;
    int ans=0;
    if(n==1) {cout<<0;return 0;}
    for(int i=1;i<=n;i++){
        for(int j=1;j<=6;j++){
            ll num = (i+1-1ll*i*int(pow(10,j)))%n+n;
            num%=n;
            if (ws(num)<=j){   //num为一个j位数 可以有前置0
                ans+=j;
                break;
            }
        }
    }
    cout<<ans<<endl;
    debug;
}

H-Wall Builder II

思路

根据题目输入,可得矩阵总面积。通过构造均值不等值,易得在最终矩形为正方形时,周长取到最值。通过暴力枚举,优先用大矩形进行填充,并且记录每次枚举最终长度 ,最后进行输出即可

代码

#include <bits/stdc++.h>
using namespace std;
#define js ios::sync_with_stdio(false);cin.tie(0); cout.tie(0)
#define debug system("pause")
#define ll long long
#define endl "\n"
#define pii pair<int, int>

const int MOD = 1e9 + 7;
const int INF = 0x3f3f3f3f;
const int N = 105;
int a[N];

void solve(){
    int n;cin>>n;
	int s = 0;
	for(int i = 1; i <= n; i++)
		s += i*(n-i+1);
	int ans;
	int len_ = floor(sqrt(s));
    vector<pii> v;
	for(int i = len_; i >= 1; i--){        //枚举宽度 
	    if(s%i != 0) continue;
		int len = s/i;
		int flg = 0;
		for(int j = 1; j <= n; j++)
			a[j] = n-j+1;
			for(int j = 1; j <= i; j++){
				int now = 0;
				while(now != len){
					for(int k = n; k >= 1; k--){
						if(a[k] && k <= len-now){
							a[k]--;
							now += k;
							v.push_back(make_pair(now, j));
							v.push_back(make_pair(now-k, j-1));
							break;
						}
						if(k == 1)
							flg = 1;	
					}
					if(flg) break;
				}
				if(flg) break;
			}
			if(!flg){
				ans = 2*i+2*len;
				break;
			}
	}
	cout<<ans<<endl;
	for(int i = v.size()-1; i >= 0; i=i-2){
		cout<<v[i].first<<" "<<v[i].second<<" "<<v[i-1].first<<" "<<v[i-1].second<<endl;
	}
}
int main(){
    js;
    int T;cin>>T;
    while(T--) solve();
    debug;
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值