题意
已知 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;
}
代码
#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;
}
思路
根据题目输入,可得矩阵总面积。通过构造均值不等值,易得在最终矩形为正方形时,周长取到最值。通过暴力枚举,优先用大矩形进行填充,并且记录每次枚举最终长度 ,最后进行输出即可
代码
#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;
}