cf ecr70 补题
a . You Are Given Two Binary Strings...
二进制乘法和十进制一样,列下竖式或者直接根据二进制定义乘一下,就会发现这个乘2^k就是把f(y)左移k位,然后观察一下就会发现只要把f(y)的最低位1 与 f(x)中向左最靠近它的那一位的1 对齐就行
b.You Are Given Two Binary Strings...
bfs一下找再不同情况下各数字间的最短路就行 ,因为数字间的搭配只有100种,所以记录一下可以少进行很多次bfs(否则会tle)
c.You Are Given a WASD-string...
题意:给定WASD组成的字符串,可以选择在字符串的一个位置插入WASD中的一个,问根据字符串在平面网格中可达的区域所在的矩形面积最小能是多少
分析:要想改变所围矩形面积,就要改变 最高/低/左/右 这四个点中至少一个,贪心的思考一下,不难发现只要记录下达到这四个点的转折点,然后在这四个点之前一位插入相反的方向,进行回溯,然后比较选出最优即可 ,注意算高度,宽度时 是 (最大-最小+1) ,要+1的
#include <bits/stdc++.h> #define fi first #define se second #define rep( i ,x ,y ) for( int i= x; i<= y ;i++ ) #define reb( i ,y ,x ) for( int i= y; i>= x ;i-- ) #define mem( a ,x ) memset( a ,x ,sizeof(a)) using namespace std; typedef long long ll; typedef pair<int ,int> pii; typedef pair<ll ,ll> pll; typedef pair<string ,int> psi; const int N = 200005; const int inf = 0x3f3f3f3f; ll t ,ans; string s; int main( ){ cin>>t; while( t-- ){ ll mnl = 0 ,mxl = 0; ll mnc = 0 ,mxc =0; cin>>s; int l = s.size( ); ll x=0 ,y = 0; rep( i ,0 ,l-1 ){ if( s[i] =='W')y++; if( s[i]=='A')x--; if( s[i]=='S')y--; if( s[i]=='D')x++; mnl = min( mnl ,x) ,mxl = max( mxl ,x); mnc = min( mnc ,y) ,mxc = max( mxc ,y); // cout<<x<<" "<<y<<endl; //cout<<mnl<<" "<<mxl<<" " <<mnc<<" "<< mxc<<endl; } ll yy = abs(mnc - mxc )+1 ,xx = abs( mnl-mxl)+1; // cout<<xx<<" "<<yy<<endl; ans = xx*yy; int pos_mnl = inf ,pos_mxl = inf ,pos_mnc = inf ,pos_mxc = inf ; x = 0 ,y = 0; rep( i ,0 ,l-1 ){ if( s[i] =='W')y++; if( s[i]=='A')x--; if( s[i]=='S')y--; if( s[i]=='D')x++; if(pos_mnl == inf && x == mnl )pos_mnl = i; if(pos_mxl == inf && x == mxl )pos_mxl = i; if(pos_mnc == inf && y == mnc )pos_mnc = i; if(pos_mxc == inf && y == mxc )pos_mxc = i; } x=0 ,y = 0; mnl = 0,mxl = 0; mnc = 0 ,mxc =0; rep( i ,0 ,l-1 ){ if( s[i] =='W')y++; if( s[i]=='A')x--; if( s[i]=='S')y--; if( s[i]=='D' )x++; if( i == pos_mnl ){ //cout <<x<<" "<<y<<endl; x += 2; mnl = min( mnl ,x) ,mxl = max( mxl ,x); mnc = min( mnc ,y) ,mxc = max( mxc ,y); // cout<<mnl<<" "<<mxl<<" "<<mnc<<" "<<mxc<<endl; x--; //cout <<x<<" "<<y<<endl; } mnl = min( mnl ,x) ,mxl = max( mxl ,x); mnc = min( mnc ,y) ,mxc = max( mxc ,y); // cout<<mnl<<" "<<mxl<<" "<<mnc<<" "<<mxc<<endl; } yy = abs(mnc - mxc )+1 ,xx = abs( mnl-mxl)+1; // cout<<xx<<" "<<yy<<endl; ans = min( ans ,xx*yy ); x=0 ,y = 0; mnl =0 ,mxl =0; mnc = 0,mxc = 0; rep( i ,0 ,l-1 ){ if( s[i] =='W')y++; if( s[i]=='A' )x--; if( s[i]=='S')y--; if( s[i]=='D' )x++; if( i == pos_mxl ){ x -= 2; mnl = min( mnl ,x) ,mxl = max( mxl ,x); mnc = min( mnc ,y) ,mxc = max( mxc ,y); x++; } mnl = min( mnl ,x) ,mxl = max( mxl ,x); mnc = min( mnc ,y) ,mxc = max( mxc ,y); } yy = abs(mnc - mxc )+1 ,xx = abs( mnl-mxl)+1; ans = min( ans ,xx*yy ); x=0 ,y = 0; mnl =0 ,mxl = 0; mnc =0 ,mxc = 0; rep( i ,0 ,l-1 ){ if( s[i] =='W' )y++; if( s[i]=='A')x--; if( s[i]=='S')y--; if( s[i]=='D' )x++; if( i == pos_mnc ){ y += 2; mnl = min( mnl ,x) ,mxl = max( mxl ,x); mnc = min( mnc ,y) ,mxc = max( mxc ,y); y--; } mnl = min( mnl ,x) ,mxl = max( mxl ,x); mnc = min( mnc ,y) ,mxc = max( mxc ,y); } yy = abs(mnc - mxc )+1 ,xx = abs( mnl-mxl)+1; ans = min( ans ,xx*yy ); x=0 ,y = 0; mnl = 0 ,mxl = 0; mnc = 0 ,mxc = 0; rep( i ,0 ,l-1 ){ if( s[i] =='W' )y++; if( s[i]=='A')x--; if( s[i]=='S' )y--; if( s[i]=='D' )x++; if( i == pos_mxc ){ y -= 2; mnl = min( mnl ,x) ,mxl = max( mxl ,x); mnc = min( mnc ,y) ,mxc = max( mxc ,y); y++; } mnl = min( mnl ,x) ,mxl = max( mxl ,x); mnc = min( mnc ,y) ,mxc = max( mxc ,y); } yy = abs(mnc - mxc )+1 ,xx = abs( mnl-mxl)+1; ans = min( ans ,xx*yy ); printf("%lld\n" ,ans); } return 0; }
(虽然代码很长,但基本都是复制的,所以只要思路清楚,写出来也耗时不长)
题意:给定n<=1e9 ,构造长度l不超过1e5由1,3,7组成的串,使得串中“1337”子串的数量恰好为n
分析:
1. 又是构造,我喜欢构造
2.这个构造思路很巧妙,构造肯定是有规律的构造的,串中1337的数量用组合数学的知识算出,组合数学有乘法原理和加法原理,乘法原理可以以较小的 l 快速增大到较大的n,加法原理对增大后的数进行微调
3.构造 n = 较大数+res = C(m1,2) + C(m2,1) ,根据式子在进行构造串
4.构造串 133 + (m2)7777... + (m1-2)3333... + 7 ,满足上述式子 ,二分m1 ,拼补m2即可
#include <bits/stdc++.h> #define fi first #define se second #define rep( i ,x ,y ) for( int i= x; i<= y ;i++ ) #define reb( i ,y ,x ) for( int i= y; i>= x ;i-- ) #define mem( a ,x ) memset( a ,x ,sizeof(a)) using namespace std; typedef long long ll; typedef pair<int ,int> pii; typedef pair<ll ,ll> pll; typedef pair<string ,int> psi; ll res; int main( ){ int t ,n ; scanf("%d" ,&t); while( t-- ){ scanf("%d" ,&n ); ll l = 0 ,r = 1e5 ,ans; while( l <= r ){ ll mid = ( l + r )>>1; ll tmp = mid*(mid-1)/2; if( tmp <= n) ans = mid ,l = mid + 1; else r = mid - 1; } res = n - ans*(ans - 1)/2; printf( "133"); ans -= 2; while( res-- )printf("7"); while( ans-- )printf("3"); printf("7\n"); } return 0; }
其他的先不补,优先补hdu的题