noip模拟78
A. F
签到题,随便写.
A_code
#include<bits/stdc++.h>
using namespace std;
namespace BSS {
#define ll long long int
#define ull unsigned ll
#define lf long double
#define lbt(x) (x&(-x))
#define mp(x,y) make_pair(x,y)
#define lb lower_bound
#define ub upper_bound
#define Fill(x,y) memset(x,y,sizeof x)
#define Copy(x,y) memcpy(x,y,sizeof x)
#define File(x) freopen(#x".in","r",stdin),freopen(#x".out","w",stdout)
inline ll read() {
ll w=0; bool cit=1; char ch;
while(!isdigit(ch=getchar())) if(ch=='-') cit=0;
while(isdigit(ch)) w=(w<<3)+(w<<1)+(ch^48),ch=getchar();
return cit?w:-w;
}
} using namespace BSS;
#define fre(x,y) freopen(#x,"r",stdin),freopen(#y,"w",stdout)
const ll N=2e3+21,M=32;
ll m,n,lg2,cnt,maxval;
ll a[N],b[N],bin[N];
unordered_map<ll,ll> vis;
signed main(){
fre(f.in,f.out);
n=read(); ll x,y,res,flag;
for(ll i=1;i<=n;i++) a[i]=read(),maxval=max(maxval,a[i]);
for(ll i=1;i<=n;i++) b[i]=read(),maxval=max(maxval,b[i]);
lg2=log2(maxval)+1,cnt=0;
for(ll i=0;i<=lg2;i++){
x=0,y=0;
for(ll j=1;j<=n;j++) if((1ll<<i)&a[j]) x++;
for(ll j=1;j<=n;j++) if((1ll<<i)&b[j]) y++;
if(x!=y and x+y!=n) puts("0"),exit(0);
}
for(ll i=1;i<=n;i++){
res=a[1]^b[i],flag=1;
for(ll j=1;j<=n;j++) vis[b[j]]=0;
for(ll j=1;j<=n;j++) vis[b[j]]++;
for(ll j=1;j<=n;j++){
if(vis[a[j]^res]) vis[a[j]^res]--;
else { flag=0; break; }
}
if(flag) bin[++cnt]=res;
}
sort(bin+1,bin+1+cnt),printf("%lld\n",cnt);
for(ll i=1;i<=cnt;i++) printf("%lld\n",bin[i]);
exit(0);
}
B. S
交换次数可以被联想成逆序对.
我们可以回想归并排序的求解过程,发现有序的依旧有序,无序的才会被交换.
本题中类比过来就是,有序的就是那些相同颜色的,也就是相同颜色的不会换位置.
于是可以写出 \(dp_{i,j,k,c}\) 表示 \(R\) 填了 \(i\) 个,\(G\) 填了 \(j\) 个,\(Y\) 填了 \(k\) 个,序列最后的字母是 \(c\) 的最小交换次数.
B_code
#include<bits/stdc++.h>
using namespace std;
namespace BSS {
#define ll int
#define ull unsigned ll
#define lf double
#define lbt(x) (x&(-x))
#define mp(x,y) make_pair(x,y)
#define lb lower_bound
#define ub upper_bound
#define Fill(x,y) memset(x,y,sizeof x)
#define Copy(x,y) memcpy(x,y,sizeof x)
#define File(x) freopen(#x".in","r",stdin),freopen(#x".out","w",stdout)
inline ll read() {
ll w=0; bool cit=1; char ch;
while(!isdigit(ch=getchar())) if(ch=='-') cit=0;
while(isdigit(ch)) w=(w<<3)+(w<<1)+(ch^48),ch=getchar();
return cit?w:-w;
}
} using namespace BSS;
const ll N=405,M=205;
ll m,n,ans;
ll c[N],cnt[3];
ll pos[3][N],pre[3][N];
ll dp[M][M][M][3];
inline void ckmin(ll &x,ll y){ x=min(x,y); }
signed main(){
File(s);
n=read(); char ch[N]; scanf("%s",ch+1);
for(ll i=1;i<=n;i++){
if(ch[i]=='R') c[i]=0; if(ch[i]=='G') c[i]=1; if(ch[i]=='Y') c[i]=2;
pos[c[i]][++cnt[c[i]]]=i; pre[0][i]=cnt[0],pre[1][i]=cnt[1],pre[2][i]=cnt[2];
// cout<<pre[0][i]<<' '<<pre[1][i]<<' '<<pre[2][i]<<endl;
}
if(cnt[0]>(n+1>>1) or cnt[1]>(n+1>>1) or cnt[2]>(n+1>>1)) puts("-1"),exit(0);
Fill(dp,0x3f),Fill(dp[0][0][0],0); ll now,nxt,res;
for(ll i=0;i<=cnt[0];i++){
for(ll j=0;j<=cnt[1];j++)
for(ll k=0;k<=cnt[2];k++){
// cout<<i<<' '<<j<<' '<<k<<' '<<dp[i][j][k][0]<<' '<<dp[i][j][k][1]<<" "<<dp[i][j][k][2] <<endl;
nxt=pos[0][i+1],res=max(0,pre[1][nxt]-pre[1][pos[1][j]])+max(0,pre[2][nxt]-pre[2][pos[2][k]]);
ckmin(dp[i+1][j][k][0],min(dp[i][j][k][1],dp[i][j][k][2])+res);
nxt=pos[1][j+1],res=max(0,pre[0][nxt]-pre[0][pos[0][i]])+max(0,pre[2][nxt]-pre[2][pos[2][k]]);
ckmin(dp[i][j+1][k][1],min(dp[i][j][k][0],dp[i][j][k][2])+res);
nxt=pos[2][k+1],res=max(0,pre[0][nxt]-pre[0][pos[0][i]])+max(0,pre[1][nxt]-pre[1][pos[1][j]]);
ckmin(dp[i][j][k+1][2],min(dp[i][j][k][0],dp[i][j][k][1])+res);
}
}
ans=min(dp[cnt[0]][cnt[1]][cnt[2]][0],dp[cnt[0]][cnt[1]][cnt[2]][1]);
ans=min(dp[cnt[0]][cnt[1]][cnt[2]][2],ans);
printf("%d\n",ans),exit(0);
}
C. Y
D. O
扫描线,不会写,先鸽了.