題目鏈接
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
*/