题目链接
F. Spy-string
题意:给你n个m长度的小写字符,现求一个字符ans,使得所有的n个字符和ans字符位数不同的字符小于等于1个。
做法:知道是暴力,但是并不是26个字符暴力的枚举,对第一个字符 当作模板 ,每次修改一个字符,修改的字符是另外几个字符的其中一个,时间复杂度:n^4
#include <bits/stdc++.h>
using namespace std;
#define rep(i,a,b) for(int i=a;i<(b);++i)
const int N=110;
int n,m;
string s[N];
string ans;
int ok(){
rep(i,0,n){
int cnt=0;
rep(j,0,m)cnt+=(ans[j]!=s[i][j]);
if(cnt>1)return 0;
}
return 1;
}
void solve(){
cin>>n>>m;
rep(i,0,n)cin>>s[i];
ans=s[0];
rep(i,0,n)
rep(j,0,m){
int t=ans[j];
ans[j]=s[i][j];
if(ok()){cout<<ans<<endl; return;}
ans[j]=t;
}
cout<<-1<<endl;
}
int main(){
int _;
cin>>_;
while(_--){
solve();
}
return 0;
}
G. A/B Matrix
题意:要你构造n*m 的矩阵 要求每行a个1 每列b个1
做法:公式a*n==b*m 必有合法,否则输出NO,至于合法的怎么构造?
第一行从第一列开始连续的填1,然后第二行开始的列位置+a 一定有合法的,为什么?考虑对每列均匀的每次加1,当行遍历完,列自然就满足每列b个了。
#pragma GCC optimize(2)
#include<bits/stdc++.h>
#define ll long long
#define maxn 1005
#define inf 1e9
#define pb push_back
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define per(i,a,b) for(int i=a;i>=b;i--)
using namespace std;
inline ll read()
{
ll x=0,w=1; char c=getchar();
while(c<'0'||c>'9') {if(c=='-') w=-1; c=getchar();}
while(c<='9'&&c>='0') {x=(x<<1)+(x<<3)+c-'0'; c=getchar();}
return w==1?x:-x;
}
const int N=55;
int n,m,a,b,ans[N][N];
int main()
{
int _=read();while(_--)
{
n=read(),m=read(),a=read(),b=read();
if(n*a!=m*b){
puts("NO");
continue;
}
rep(i,1,n) rep(j,1,m) ans[i][j]=0;
int id=1;
for(int i=1;i<=n;++i){
for(int num=1;num<=a;++num,id=(id+1)%(m+1))
{
if(id==0) id=1;
ans[i][id]=1;
}
}
puts("YES");
rep(i,1,n)
{
rep(j,1,m) printf("%d",ans[i][j]);
puts("");
}
}
}
/*
10
3 3 2 2
*/
H. Binary Median
题意:给你m代表有2^m 个不同的01串,现在去掉n个,问剩下的2^m-n个串中 排序后中位的字符串. 中位计算:(id-1)/2
做法:因为m只有60,考虑字符串当作longlong的整数来算。最初的中位数一定是01111形式就是2^(m-1)-1.
然后n只有100,考虑对初始的中位数上下枚举100个数,然后判断小于当前数和大于当前数是否相等。
至于怎么 去掉 n 的 影响。对当前数在n中二分查找大于当前数x的个数。那么大于x的个数就少了这么多。简单吧
#pragma GCC optimize(2)
#include<bits/stdc++.h>
#define ll long long
#define maxn 1005
#define inf 1e9
#define pb push_back
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define per(i,a,b) for(int i=a;i>=b;i--)
using namespace std;
inline ll read()
{
ll x=0,w=1; char c=getchar();
while(c<'0'||c>'9') {if(c=='-') w=-1; c=getchar();}
while(c<='9'&&c>='0') {x=(x<<1)+(x<<3)+c-'0'; c=getchar();}
return w==1?x:-x;
}
const int N=1e2+10;
char s[N];
int n,m;
ll X[N],len,now,L,R;
ll cal(char s[])
{
ll now=1,ans=0;
for(int i=m;i>=1;--i){
if(s[i]=='1') ans+=now;
now*=2;
}
return ans;
}
map<ll,int>mp;
void print(ll x)
{
stack<int>sta;
while(x) {
sta.push(x%2);
x=x/2;
}
int len=sta.size();
rep(i,1,m-len) sta.push(0);
while(sta.size()){
printf("%d",sta.top());
sta.pop();
}
}
int valid(ll x)
{
//printf("x:%lld\n",x);
ll mx=R-x,mi=x+1;
int id=lower_bound(X+1,X+1+len,x)-X;
int t1=len-id+1;
mi-=(id-1);
mx-=t1;
//printf("x:%lld mi:%lld mx:%lld t1:%d\n",x,mi,mx,t1);
if(mx==mi||mx+1==mi) return 1;
return 0;
}
int main()
{
int _=read();
while(_--)
{
n=read(),m=read();
mp.clear();
now=(1ll<<(m-1))-1;
L=0,R=(1ll<<m)-1;
len=0;
rep(i,1,n){
scanf("%s",s+1);
X[++len]=cal(s);
mp[X[len]]=1;
}
sort(X+1,X+1+len);
ll ans=now;
//printf("ansans:%lld now:%lld\n",ans,now);
int flag=1;
for(int i=1;i<=100&&ans>=0&&flag;++i){
if(mp[ans]==0&&valid(ans)){
print(ans);
flag=0;
break;
}
ans--;
}
ans=now;
for(int i=1;i<=100&&ans<=R&&flag;++i){
if(mp[ans]==0&&valid(ans)){
print(ans);
flag=0;
break;
}
ans++;
}
puts("");
}
}
/*
1
7 3
000
001
010
100
101
110
111
*/