ZROI普及五连测Day4

ZROI普及五连测 \(Day4\)

ZROI普及五连测 \(Day4\)

A.刷题王者

水题,略

B.回到原点

先把能抵消的全部抵消,剩下的就是需要调整的.
剩下的一定是不能抵消的,而且 \(U,D\) 和 \(L,R\) 两组一定是每组至多剩一种没有匹配完.

调整的时候,考虑自身内部调整和相互匹配,取 \(min\) 即可.

#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <string>
#include <vector>
#include <stack>
#include <queue>
#include <cmath>
#include <ctime>
#include <map>
#include <set>
#define MEM(x,y) memset ( x , y , sizeof ( x ) )
#define rep(i,a,b) for (int i = (a) ; i <= (b) ; ++ i)
#define per(i,a,b) for (int i = (a) ; i >= (b) ; -- i)
#define pii pair < int , int >
#define one first
#define two second
#define rint read<int>
#define pb push_back
#define db double
#define ull unsigned long long
#define lowbit(x) ( x & ( - x ) )
#define mabs(x) ( x < 0 ? - x : x )

using std::queue ;
using std::set ;
using std::pair ;
using std::max ;
using std::min ;
using std::priority_queue ;
using std::vector ;
using std::swap ;
using std::sort ;
using std::unique ;
using std::greater ;

template < class T >
    inline T read () {
        T x = 0 , f = 1 ; char ch = getchar () ;
        while ( ch < '0' || ch > '9' ) {
            if ( ch == '-' ) f = - 1 ;
            ch = getchar () ;
        }
       while ( ch >= '0' && ch <= '9' ) {
            x = ( x << 3 ) + ( x << 1 ) + ( ch - 48 ) ;
            ch = getchar () ;
       }
       return f * x ;
    }

const int N = 1e3 + 10 ;

char s[N] ;
int v[N] , w[N] ;
int n , x , y ;
int cnt[4] ;

signed main (int argc , char * argv[]) {
    scanf ("%s" , s + 1 ) ; n = strlen ( s + 1 ) ;
    if ( n & 1 ) return puts ("-1") , 0 ;
    rep ( i , 1 , n ) if ( s[i] == 'U' ) v[i] = 1 ; else if ( s[i] == 'D' ) v[i] = - 1 ;
    rep ( i , 1 , n ) if ( s[i] == 'L' ) w[i] = 1 ; else if ( s[i] == 'R' ) w[i] = - 1 ;
    rep ( i , 1 , n ) { v[i] += v[i-1] ; w[i] += w[i-1] ; }
    x = abs ( v[n] ) ; y = abs ( w[n] ) ;
    if ( ( x + y ) & 1 ) return puts ("-1") , 0 ;
    if ( x == y ) printf ("%d\n" , x ) ;
    else {
        int del = abs ( x - y ) ;
        if ( x > y ) x -= del , y += del ;
        else x += del , y -= del ;
        if ( ( x & 1 ) && ( y & 1 ) ) {
            int tmp = x / 2 + y / 2 + 1 ;
            printf ("%d\n" , min ( del + x , tmp ) ) ;
        } else {
            int tmp = x / 2 + y / 2 ;
            printf ("%d\n" , min ( del + x , tmp ) ) ;
        }
    }
    return 0 ;
}

C.快乐矩阵

把矩阵黑白间隔染色 \(:\)
ZROI普及五连测Day4
你发现,每次一定是选择一个黑格子,一个白格子.

然后由于是矩阵,所以我们一定可以构造出一条从 \((1,1)\) 到 \((n,m)\) 的不重不漏的路径.

每次沿着这样的路径一路修改下去,每次操作把上一个格子清零,这样一定能推到最后.

到最后能置为全 \(0\) 的充要条件一定是黑格子之和等于白格子之和.

愉快 \(AC\) .

#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <string>
#include <vector>
#include <queue>
#include <cmath>
#include <ctime>
#include <map>
#include <set>
#define MEM(x,y) memset ( x , y , sizeof ( x ) )
#define rep(i,a,b) for (int i = (a) ; i <= (b) ; ++ i)
#define per(i,a,b) for (int i = (a) ; i >= (b) ; -- i)
#define pii pair < int , int >
#define one first
#define two second
#define rint read<int>
#define int long long
#define pb push_back
#define db double
#define ull unsigned long long
#define lowbit(x) ( x & ( - x ) )

using std::queue ;
using std::set ;
using std::pair ;
using std::max ;
using std::min ;
using std::priority_queue ;
using std::vector ;
using std::swap ;
using std::sort ;
using std::unique ;
using std::greater ;

template < class T >
    inline T read () {
        T x = 0 , f = 1 ; char ch = getchar () ;
        while ( ch < '0' || ch > '9' ) {
            if ( ch == '-' ) f = - 1 ;
            ch = getchar () ;
        }
       while ( ch >= '0' && ch <= '9' ) {
            x = ( x << 3 ) + ( x << 1 ) + ( ch - 48 ) ;
            ch = getchar () ;
       }
       return f * x ;
    }

const int N = 5e2 + 11 ;

int idx , res1 , res2 ;
int e[N][N] , n , m ;
bool stats[N] ;

signed main (int argc , char * argv[]) {
    n = rint () ; m = rint () ;
    rep ( i , 1 , n ) rep ( j , 1 , m ) e[i][j] = rint () ;
    rep ( i , 1 , m ) stats[i] = stats[i-1] ^ 1 ;
    rep ( i , 1 , n ) rep ( j , 1 , m ) {
        if ( i & 1 ) {
            if ( stats[j] ) res1 += e[i][j] ;
            else res2 += e[i][j] ;
        } else {
            if ( stats[j] ) res2 += e[i][j] ;
            else res1 += e[i][j] ;
        }
    }
    puts ( res1 == res2 ? "Yes" : "No" ) ;
    return 0 ;
}

D.梦中的位运算

明白这样一个事实 \(:\)

\[x^2+y^2\le (x\&y)^2 + (x|y)^2\]

引理 \(:\)
\(1\)守恒定律 \(:\) 在该题目叙述的系统中,\(1\)既不会凭空产生也不会凭空消失,只会从一个元素转移到另一个元素,系统中 \(1\) 的代数和时时刻刻保持不变.(滑稽.jpg)

所以...你贪心地把所有 \(1\) 堆一起就好了...

#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <string>
#include <vector>
#include <queue>
#include <cmath>
#include <ctime>
#include <map>
#include <set>
#define MEM(x,y) memset ( x , y , sizeof ( x ) )
#define rep(i,a,b) for (int i = (a) ; i <= (b) ; ++ i)
#define per(i,a,b) for (int i = (a) ; i >= (b) ; -- i)
#define pii pair < int , int >
#define one first
#define two second
#define rint read<int>
#define int long long
#define pb push_back
#define db double
#define ull unsigned long long
#define lowbit(x) ( x & ( - x ) )

using std::queue ;
using std::set ;
using std::pair ;
using std::max ;
using std::min ;
using std::priority_queue ;
using std::vector ;
using std::swap ;
using std::sort ;
using std::unique ;
using std::greater ;

template < class T >
    inline T read () {
        T x = 0 , f = 1 ; char ch = getchar () ;
        while ( ch < '0' || ch > '9' ) {
            if ( ch == '-' ) f = - 1 ;
            ch = getchar () ;
        }
       while ( ch >= '0' && ch <= '9' ) {
            x = ( x << 3 ) + ( x << 1 ) + ( ch - 48 ) ;
            ch = getchar () ;
       }
       return f * x ;
    }

const int N = 1e5 + 100 ;

int n , v[N] , cnt[65] , g[65] , ans ;

vector < bool > tmp ;
inline void divide (int x) {
    tmp.clear () ;
    while ( x ) { tmp.pb ( x & 1ll ) ; x >>= 1ll ; }
    // for (int k : tmp) printf ("%lld " , k ) ; puts ("") ;
    for (int i = 0 ; i < tmp.size () ; ++ i)
        if ( tmp[i] ) ++ cnt[i] ;
    return ;
}
 
inline int quick (int a , int p) {
    int res = 1ll ;
    while ( p ) {
        if ( p & 1ll ) res *= a ;
        a *= a ; p >>= 1ll ;
    }
    return res ;
}

signed main (int argc , char * argv[]) {
    n = rint () ; rep ( i , 1 , n ) v[i] = rint () ;
    rep ( i , 0 , 62 ) g[i] = quick ( 2ll , i ) ; 
    rep ( i , 1 , n ) divide ( v[i] ) ;
    // rep ( i , 0 , 4 ) printf ("%lldth : %lld\n" , i , cnt[i] ) ;
    rep ( i , 1 , n ) {
        int res = 0 ;
        per ( j , 62 , 0 ) if ( cnt[j] ) -- cnt[j] , res += g[j] ;
        v[i] = res ;
    }
    rep ( i , 1 , n ) ans += v[i] * v[i] ;
    printf ("%lld\n" , ans ) ;
    return 0 ;
}
上一篇:[考试总结]ZROI-21-十一集训-赠送赛 总结


下一篇:ZROI十一集训Day2