#include <bits/stdc++.h>
using namespace std;
const int AX = 1e3+66;
struct Node{
int id,s;
bool friend operator < ( const Node &a , const Node &b ){
if(a.s != b.s) return a.s > b.s;
else return a.id < b.id;
}
}G[AX];
int a, n, b, c, d;
int main() {
cin >> n;
for(int i = 1; i <= n; i ++) {
cin >> a >> b >> c >> d;
G[i].id = i;
G[i].s = a+b+c+d;
}
sort(G+1,G+1+n);
for(int i = 1; i <= n; i ++)
if(G[i].id == 1) return 0*printf("%d\n",i);
return 0;
}
B
题意:给两个串s,t,要求反转s中任意两个字母,使得 两个0,1串或值改变。
思路:t是0,s对应位置为0时,找s中1交换,t是1,s对应位置是0,找s中0交换,最后减去重复的。
Code:
#include <bits/stdc++.h>
#pragma comment(linker, “/STACK:1024000000,1024000000”)
#define INF 0x3f3f3f3f
#define LL long long
using namespace std;
const int AX = 1e5+66;
char a[AX];
char b[AX];
int main(){
int n ;
scanf("%d",&n);
scanf("%s%s",a+1,b+1);
int cur = 0 ;
long long res = 0 ;
long long x = 0 , y = 0 , x1 = 0 , y1 = 0 ;
for( int i = 1 ; i <= n ; i++ ){
if( b[i] == '0' && a[i] == '0' ){
x ++ ;
}
if( b[i] == '0' && a[i] == '1' ){
y ++ ;
}
if( a[i] == '0' ) x1++ ;
else y1 ++ ;
}
cout << ( x1*y + x*y1 - x * y) << endl;
return 0 ;
}
C
题意:要求输出一个1-n的全排列,使得LIS+LDS长度最小
思路:每段长度sqrt(n)输出
Code:
#include <bits/stdc++.h>
#pragma comment(linker, “/STACK:1024000000,1024000000”)
#define INF 0x3f3f3f3f
#define LL long long
using namespace std;
const int AX = 1e6+6;
int a[AX];
int main(){
int n;
scanf("%d",&n);
int len = sqrt(n);
int tot = n ;
for( int i = 1 ; i <= n ; i += len ){
for( int j = min( i + len - 1 , n ) ; j >= i ; j-- ){
a[j] = tot--;
}
}
for( int i = 1 ; i <= n ; i++ ){
printf("%d%c",a[i],"\n "[i<n]);
}
return 0 ;
}
D
题意:给n为每个串长度,还有n个值,对应每个位置的价值,m个串,q个询问。要求每个询问输入一个串和一个价值,输出m个串里面与这个串相同位置价值之和小于给的价值(<100)的个数。
思路:n的范围是12,(1<<12==4096),可以预处理出所有值到m中所有串的和<100的个数,然后再求个前缀和,查询的时候直接输出即可。
Code:
#include <bits/stdc++.h>
#pragma comment(linker, “/STACK:1024000000,1024000000”)
#define INF 0x3f3f3f3f
#define LL long long
using namespace std;
const int AX = 5e3;
int a[20];
int sum[AX][102];
int num[AX];
int main(){
int n , m , q ;
scanf("%d%d%d",&n,&m,&q);
for( int i = 0 ; i < n ; i++ ){
scanf("%d",&a[i]);
}
char s[20];
for( int i = 0 ; i < m ; i++ ){
scanf("%s",s);
int tmp = 0 ;
for( int j = n - 1 ; j >= 0 ; j-- ){
if( s[j] == '1' ){
tmp += ( 1 << (n-1-j) );
}
}
num[tmp] ++;
}
int MAX = ( 1 << n );
for( int i = 0 ; i < MAX ; i++ ){
for( int j = 0 ; j < MAX ; j++ ){
if( num[j] ){
int tmp = 0 ;
for( int k = 0 ; k < n ; k++ ){
if( ( i & ( 1 << k ) ) == ( j & ( 1 << k ) ) ){
tmp += a[n-k-1];
}
}
if( tmp <= 100 ){
sum[i][tmp] += num[j];
}
}
}
}
for( int i = 0 ; i <= MAX ; i++ ){
for( int j = 1 ; j <= 100 ; j++ ){
sum[i][j] += sum[i][j-1];
}
}
int v ;
while( q-- ){
scanf("%s%d",s,&v);
int tmp = 0 ;
for( int j = n - 1 ; j >= 0 ; j-- ){
if( s[j] == '1' ){
tmp += ( 1 << (n-1-j) );
}
}
printf("%d\n",sum[tmp][v]);
}
return 0 ;
}