Pinely Round 4 (Div. 1 + Div. 2) 覆盤總結

legendcn發表於2024-07-29

Pinely Round 4 (Div. 1 + Div. 2)

發揮到極致了,寫出了兩題

A. Maximize the Last Element

對於每個滿足他左邊的數的個數和他後面的數的個數都是奇數的數,取最大值即可。

# include<bits/stdc++.h>
using namespace std;
typedef long long ll; 
// # define int long long
# define lc u << 1
# define rc u << 1 | 1
# define fi first
# define se second
const int N = 105;

int n;
signed main ()
{
    int T; scanf ("%d", &T);
    while (T -- )
    {
        scanf ("%d", &n); 
        int mx = 0;
        for (int i = 1; i <= n; i ++ )
        {
            int x; scanf ("%d", &x);
            if ((i - 1) % 2 == 0 && (n - i) % 2 == 0) mx = max (mx, x);
        }
        printf ("%d\n", mx);
    }
    return 0;
}

B. AND Reconstruction

對於每個位置 \(i\),他與前面位置的公共部分為 \(b_{i-1}\),與後面公共部分是 \(b_i\)。所以這個位置至少是 \(b_{i-1} | b_i\)。如果這個時候不滿足,就判定誤解。如果滿足,那麼構造就是這個啦。

# include<bits/stdc++.h>
using namespace std;
typedef long long ll; 
// # define int long long
# define lc u << 1
# define rc u << 1 | 1
# define fi first
# define se second
const int N = 100005;

int n;
int b[N], a[N];
signed main ()
{
    int T; scanf ("%d", &T);
    while (T -- )
    {
        scanf ("%d", &n);
        for (int i = 1; i < n; i ++ ) scanf ("%d", &b[i]);
        a[1] = b[1], a[n] = b[n - 1];
        for (int i = 2; i < n; i ++ ) a[i] = b[i - 1] | b[i];
        bool flag = 1;
        for (int i = 1; i < n; i ++ )
        {
            if ((a[i] & a[i + 1]) != b[i])
            {
                flag = 0;
                break;
            }
        }
        if (!flag)
        {
            printf ("-1\n");
            continue;
        }
        for (int i = 1; i <= n; i ++ ) printf ("%d ", a[i]);
        printf ("\n");
    }
    return 0;
}

C. Absolute Zero

看到 \(n\le 2\times 10^5,k\le 40\),就很容易想到拆位。首先,如果序列中有兩個數機奇偶性不同,就肯定無法把整個序列變成 \(0\),因為這兩個數永遠差著一個 \(1\)。所以,如果存在兩個奇偶性不同的數,就判定無解。否則,就從大到小的每一個二進位制位進行操作即可。

# include<bits/stdc++.h>
using namespace std;
typedef long long ll; 
// # define int long long
# define lc u << 1
# define rc u << 1 | 1
# define fi first
# define se second
const int N = 200005;

int n;
int a[N];
signed main ()
{
	int T; scanf ("%d", &T);
	while (T -- )
	{
		scanf ("%d", &n);
		for (int i = 1; i <= n; i ++ ) scanf ("%d", &a[i]);
		bool flag = 0;
		for (int i = 2; i <= n; i ++ )
		{
			if (a[i] % 2 != a[1] % 2)
				flag = 1;
		}
		if (flag)
		{
			printf ("-1\n");
			continue;
		}
		if (a[1] % 2 == 0)
		{
			printf ("31\n");
			for (int i = 29; i >= 0; i -- ) printf ("%d ", (1ll << i));
			printf ("1\n");
		}
		else
		{
			printf ("30\n");
			for (int i = 29; i >= 0; i -- ) printf ("%d ", (1ll << i));
			printf ("\n");
		}
	}
	return 0;
}

D. Prime XOR Coloring

玄學題,我知道構造方法,但是我不知道怎麼想到的題。
那麼我就只能給出構造方法以及證明了。

構造方法

  • \(n=1\)1
  • \(n=2\)1 2
  • \(n=3\)1 2 2
  • \(n=4\)1 2 2 3
  • \(n=5\)1 2 2 3 3
  • \(n\ge 6\)2 3 4 1 2 3 4 1 2 3 4 1 ...

證明

首先,\(n\le 5\) 的十分好證。
對於 \(n\ge 6\) 的情況,如果兩個點顏色相同,那麼他們異或起來一定是 \(4\) 的倍數,不是質數,所以沒有邊。
證畢。

# include<bits/stdc++.h>
using namespace std;
typedef long long ll; 
// # define int long long
# define lc u << 1
# define rc u << 1 | 1
# define fi first
# define se second

signed main ()
{
    int T; scanf ("%d", &T);
    while (T -- )
    {
        int n; scanf ("%d", &n);
        if (n == 1) printf ("1\n1\n");
        else if (n == 2) printf ("2\n1 2\n");
        else if (n == 3) printf ("2\n1 2 2\n");
        else if (n == 4) printf ("3\n1 2 2 3\n");
        else if (n == 5) printf ("3\n1 2 2 3 3\n");
        else
        {
            printf ("4\n");
            for (int i = 1; i <= n; i ++ ) printf ("%d ", i % 4 + 1); 
            printf ("\n");
        }
    }
    return 0;
}

相關文章