A:當 \(n,m\) 確定後,整張表只有 \(2\) 種情況,分別檢查是否符合原表。
點選檢視程式碼
#include<bits/stdc++.h>
#define int long long
#define psbk push_back
#define fst first
#define scd second
#define umap unordered_map
#define pqueue priority_queue
#define vc vector
#define endl '\n'
#define all(v) v.begin(), v.end()
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair<int, int> pii;
constexpr int inf = 0x3f3f3f3f;
int n, m;
char a[55][55];
void solve()
{
cin >> n >> m;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
cin >> a[i][j];
}
}
for(int _=0;_<2;_++)
{
bool fg = 0;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
if(a[i][j] != '.' && (a[i][j] == 'R') != ((i + j) % 2 == _))
{
fg = 1;
break;
}
}
if(fg)
{
break;
}
}
if(fg)
{
continue;
}
cout << "YES" << endl;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
cout << ((i + j) % 2 == _ ? 'R' : 'W');
}
cout << endl;
}
return;
}
cout << "NO" << endl;
}
signed main()
{
// freopen("1.in","r",stdin);
// freopen("1.out","w",stdout);
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int tt;
cin >> tt;
while(tt--)
{
solve();
}
return 0;
}
B:對於一次選擇 \(i\) 的操作,當且僅當 \(a_i > a_{i-1}\) 且 \(a_i > a_{i+1}\) 會使醜陋值減小。於是對這些位置不斷操作,直到 \(a_i=max(a_{i-1}, a_{i+1})\)。(\(a_0=a_{n+1}=0\))
點選檢視程式碼
#include<bits/stdc++.h>
#define int long long
#define psbk push_back
#define fst first
#define scd second
#define umap unordered_map
#define pqueue priority_queue
#define vc vector
#define endl '\n'
#define all(v) v.begin(), v.end()
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair<int, int> pii;
constexpr int inf = 0x3f3f3f3f;
int n, a[400005];
void solve()
{
cin >> n;
int ans = 0;
for(int i=1;i<=n;i++)
{
cin >> a[i];
ans += abs(a[i] - a[i - 1]);
}
ans += a[n];
a[n + 1] = 0;
for(int i=1;i<=n;i++)
{
if(a[i] > a[i - 1] && a[i] > a[i + 1])
{
ans -= a[i] - max(a[i - 1], a[i + 1]);
}
}
cout << ans << endl;
}
signed main()
{
// freopen("1.in","r",stdin);
// freopen("1.out","w",stdout);
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int tt;
cin >> tt;
while(tt--)
{
solve();
}
return 0;
}
C:將兩行分別記為 \(a_1\sim a_n, b_1\sim b_n\),再找到 \(b\) 的逆排列,即排列 \(b'\),滿足 \(b'_{b_i}=i\)。考慮一張 \(n\) 個點(編號 \(1\sim n\))的圖,對所有 \(1\le i\le n\),連邊 \((i, b'_{a_i})\)。此圖由若干個環組成,每個環必須同時 換/不換,故答案為 \(2^{環的個數}\)。
點選檢視程式碼
#include<bits/stdc++.h>
#define int long long
#define psbk push_back
#define fst first
#define scd second
#define umap unordered_map
#define pqueue priority_queue
#define vc vector
#define endl '\n'
#define all(v) v.begin(), v.end()
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair<int, int> pii;
constexpr int inf = 0x3f3f3f3f, mo = 1000000007;
int n, a[400005], b[400005], pa[400005], pb[400005];
bool vis[400005];
int qpw(int x, int y)
{
if(!y)
{
return 1;
}
int tmp = qpw(x, y / 2);
return tmp * tmp % mo * (y % 2 ? x : 1) % mo;
}
void solve()
{
cin >> n;
for(int i=1;i<=n;i++)
{
cin >> a[i];
pa[a[i]] = i;
vis[i] = 0;
}
for(int i=1;i<=n;i++)
{
cin >> b[i];
pb[b[i]] = i;
}
int cnt = 0;
for(int i=1;i<=n;i++)
{
if(!vis[i])
{
vis[i] = 1;
for(int j=pb[a[i]];j-i;j=pb[a[j]])
{
vis[j] = 1;
}
cnt++;
}
}
cout << qpw(2, cnt) << endl;
}
signed main()
{
// freopen("1.in","r",stdin);
// freopen("1.out","w",stdout);
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int tt;
cin >> tt;
while(tt--)
{
solve();
}
return 0;
}
D:先查詢 \(1\),將 \(2\sim n\) 根據到 \(1\) 距離的奇偶性分為兩個集合(樹一定是二分圖!!),然後查詢較小集合中的所有數,即可得知所有邊。最差步數為 $1 + \left \lfloor \dfrac{n-1}{2} \right \rfloor = \left \lfloor \dfrac{n+1}{2} \right \rfloor = \left \lceil \dfrac{n}{2} \right \rceil $。
Trick:圖論構造題,很多與二分圖相關,特別是看到 \(\dfrac{n}{2}\) 時。
點選檢視程式碼
#include<bits/stdc++.h>
#define int long long
#define psbk push_back
#define fst first
#define scd second
#define umap unordered_map
#define pqueue priority_queue
#define vc vector
#define all(v) v.begin(), v.end()
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair<int, int> pii;
constexpr int inf = 0x3f3f3f3f;
int n, d[2005];
vc<int> v[2];
vc<pii> ans;
signed main()
{
// freopen("1.in","r",stdin);
// freopen("1.out","w",stdout);
cin >> n;
cout << "? 1" << endl;
for(int i=1;i<=n;i++)
{
cin >> d[i];
if(i != 1)
{
v[d[i] % 2].psbk(i);
}
}
if(v[0].size() < v[1].size())
{
for(int i=1;i<=n;i++)
{
if(d[i] == 1)
{
ans.psbk({1, i});
}
}
for(int i : v[0])
{
cout << "? " << i << endl;
for(int j=1;j<=n;j++)
{
cin >> d[j];
if(d[j] == 1)
{
ans.psbk({i, j});
}
}
}
}
else
{
for(int i : v[1])
{
cout << "? " << i << endl;
for(int j=1;j<=n;j++)
{
cin >> d[j];
if(d[j] == 1)
{
ans.psbk({i, j});
}
}
}
}
cout << '!' << endl;
for(pii i : ans)
{
cout << i.fst << ' ' << i.scd << endl;
}
return 0;
}