Codeforces Round #502 (in memory of Leopoldo Taravilse, Div. 1 + Div. 2) A~~D

/**

A. The Rank
链接:https://codeforces.com/contest/1017/problem/A
题意:Thomas's rank 暴力 排序均可
*/
// eg:test 1
#include<bits/stdc++.h>
using namespace std;


struct node{
    int sum,id;
    bool operator<(const node&x)const{
        if(sum!=x.sum)return sum>x.sum;
		 else return id<x.id;
    }
}a[3001];

int e,b,c,d;

int main(){
	int n;scanf("%d",&n);
    for(int i=1;i<=n;i++){
        scanf("%d %d %d %d",&e,&b,&c,&d);
        a[i].sum=b+c+d+e;
        a[i].id=i;
    }
    sort(a+1,a+n+1);
    for(int i=1;i<=n;i++){
        if(a[i].id==1){
            printf("%d\n",i);
            break;
        }
    }
    return 0;
}
*/

//eg:test2
#include<bits/stdc++.h>
using namespace std;
int main (){
	int n;scanf("%d",&n);
	int ans=1;
	int a,b,c,d;scanf("%d %d %d %d",&a,&b,&c,&d);
	int sum=a+b+c+d;
	for(int i=1;i<n;i++){ 
		scanf("%d %d %d %d",&a,&b,&c,&d);
	    if(sum<(a+b+c+d)) ans++;
    }
    printf("%d\n",ans);
 	return 0;
}

/**
B. The Bits
链接:https://codeforces.com/contest/1017/problem/B
题意:给定二进制串a b 
c=a^b 交换a串的任意两个位置 使得改变后的a串和b串进行异或 不等于c
  01  01 01 
  00  11 01
umm  一共就上述的3种case 可直接暴力或者容斥一部分进行计算
*/

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn = 1e5+7;
int n;
char s[maxn];
char s1[maxn];
vector<int>V1;
vector<int>V2;

void solved(){
	scanf("%d",&n);scanf("%s",s);scanf("%s",s1);
    ll cnt1=0;
    ll cnt0=0;
    for(int i=0;i<n;i++){
        if(s[i]=='0') cnt0++;
        else cnt1++;
        if(s[i]=='0'&&s1[i]=='0') V1.push_back(i);
        else if(s[i]=='1'&&s1[i]=='0') V2.push_back(i);

    }
    ll ans=cnt1*V1.size();
    ans+=cnt0*V2.size();
    ans-=V1.size()*(ll)V2.size();
    ans=max(ans,0ll);
    cout<<ans<<endl;
}

int main(){
   solved();
   return 0;
}

/**
C. The Phone Number
链接:https://codeforces.com/contest/1017/problem/C
题意:构造一个1-->n的全排列 最小化 sum = len(LIS)+len (lDS)
均分sqrt块 从后往前进行输出 
*/
#include<bits/stdc++.h>
using namespace std;
int n,tmp,m,now;
int main(){
	scanf("%d",&n);
	m=sqrt(n);
	if(m*m!=n) m++;
	tmp=m;int i;
	while(tmp--){
		now++;
		for(i=max(1,n-now*m+1);i<=n-now*m+m;i++) printf("%d ",i);
	}
    return 0;
}
/**
D. The Wu.cpp
链接:https://codeforces.com/contest/1017/problem/D
题意:给定m个01串 看所给Q个序列所给某个01串,与上述的m个串进行匹配
匹配:相同则对应位置填1 不同则为0 转换为二进制后对应n位置上权值为小于等于k的个数 
********************tricks***************
11 11 匹配之后为 11 也就是权值前缀和了  不匹配(eg:10 01) 则权值为0;

分析:
由于k<=100 可事先利用C数组记录m中每个01串出现的次数 
再对于所有可能的询问 预处理出000000000000~111111111111 的答案
用f[i][j]进行o(1)查询
f[i][j]:二进制值为i时对应n个01串进行匹配的不超过j的个数的前缀和;
*/

#include<bits/stdc++.h>
using namespace std;
const int maxn=5e5+7;
int Q,m,n,a[maxn],c[maxn],ans,f[5001][101],d[1001];
char b[maxn][13];

void dfs(int x,int now,int mid,int sum){
	if(x>n){
		if(mid<=100) f[sum][mid]+=c[now];
		return;
	}
	dfs(x+1,now*2+1,mid+(d[x]==1?a[x]:0),sum);
	dfs(x+1,now*2,mid+(d[x]==0?a[x]:0),sum);
}
char s[10001];
int main(){
	int now,t,ha;
	scanf("%d %d %d",&n,&m,&Q);
	for(int i=1;i<=n;i++) scanf("%d",&a[i]);
	for(int i=1;i<=m;i++){
		now=0;
		scanf("%s",b[i]+1);
		for(int j=1;j<=n;j++) now=now*2+(b[i][j]=='1');
		c[now]++;
	}
	for(int i=0;i<(1<<n);i++){
		now=i;
		ha=0;
		for(int j=1;j<=n;j++){
			d[j]=now%2;
			ha=ha*2+d[j];
			now/=2;
		}
		dfs(1,0,0,ha);
	}

	for(int i=0;i<(1<<n);i++)
	   for(int j=1;j<=100;j++)
	 	   f[i][j]+=f[i][j-1];

	while(Q--){
		scanf("%s%d",s+1,&t);
		now=0;
		for(int i=1;i<=n;i++) now=now*2+(s[i]=='1');
		printf("%d\n",f[now][t]);
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/hypHuangYanPing/article/details/81536023