题目链接:The 2023 ICPC Xi'an Invitational Programming Contest - 比赛主页 - 比赛 - QOJ.ac
G. Permutation
思路
纯签到没啥好说的
代码
void solve(){
int n;
cin>>n;
for(int i=1;i<=n;i++){
cout<<i<<" ";
}
}
J. Target
思路
可以对a进行的操作:1. 2.
对于0<=a<=1我们发现操作1能让a变小,操作2能让a变大
我们可以尝试先把a变成0,再把a变成b,暴力打表发现第一步最大不会超过15,第二步不会超过20,直接暴力搜索即可
代码
#include<bits/stdc++.h>
using namespace std;
#define vcoistnt ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);
#define int long long
#define vi vector<int>
#define vb vector<bool>
typedef pair<int,int> pll;
const int N=2e5+10;
const int inf=1e18;
const int mod=998244353;
const double eps=1e-4;
void solve(){
vector<int> ans;
double a,b;
cin>>a>>b;
while(a>eps){
a/=2;
ans.push_back(1);
}
vector<int> t(50,0);
bool f=false;
auto dfs=[&](auto self,double x,int ct)->void{
if(f||ct>20) return;
if(abs(x-b)<=eps){
for(int i=0;i<ct;i++){
cout<<t[i];
}
f=true;
return;
}
t[ct]=1;
self(self,(x*1.0)/2,ct+1);
t[ct]=2;
self(self,(x*1.0)/2+0.5,ct+1);
};
for(int i:ans){
cout<<i;
}
dfs(dfs,0,0);
}
signed main() {
vcoistnt
cout<<fixed<<setprecision(2);
int _=1;
// cin>>_;
while(_--) solve();
return 0;
}
A. Alice and Bob
思路
此题思路模拟样例就能得出
当以p[1]为开头的时候,p[1]长度内p[1]后面的数必须大于p[1]才能使得Bob获胜
那么这题就变成了组合数学的问题,
将所有开头的情况枚举,答案相加即可
代码
#include<bits/stdc++.h>
using namespace std;
#define vcoistnt ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);
#define int long long
#define vi vector<int>
#define vb vector<bool>
typedef pair<int,int> pll;
const int N=1e7+10;
const int inf=1e18;
const int mod=998244353;
int fac[N];
int inv[N];
int ksm(int a,int b){
int ans=1;
while(b){
if(b&1){
ans=(ans*a)%mod;
}
a=((a%mod)*(a%mod))%mod;
b>>=1;
}
return ans;
}
int C(int n,int m){
if(m>n) return 0;
return fac[n] * inv[m]%mod * inv[n-m]%mod;
}
void init(){
fac[0]=1;
inv[0]=1;
for(int i=1;i<N;i++){
fac[i]=(fac[i-1]*i)%mod;
}
inv[N-1]=ksm(fac[N-1],mod-2);
for(int i=N-2;i>=1;i--){
inv[i]=inv[i+1]*(i+1)%mod;
}
}
int A(int n,int m){
if(m>n || m<0 || n<0){
return 0;
}
return fac[n]*inv[n-m]%mod;
}
void solve(){
int n;cin>>n;
int ans=0;
for(int i=1;i<=n;i++){
ans=(ans+A(n-i,i-1)*A(n-i,n-i))%mod;
}
cout<<ans<<"\n";
}
signed main() {
vcoistnt
cout<<fixed<<setprecision(2);
int _=1;
init();
// cin>>_;
while(_--) solve();
return 0;
}
H. Spin the Wheel
思路
严格证明不是很会,只能说这题做出来全凭经验找规律猜结论,多观察几个例子我们发现,当我们在旋转之后加我们不会影响相邻两数之间差值%n的相等性,如果差值%n不相等直接输出-1
但相邻两数之间的差值%n是可以改变的,我们发现我们每进行一次操作便能使差值+1,然后我们贪心的求最小值,那么答案便是差值%n,如果a[0]!=0便需要再操作1次
特殊如果所有值都相等时特判一下
代码
#include<bits/stdc++.h>
using namespace std;
#define vcoistnt ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);
#define int long long
#define vi vector<int>
#define vb vector<bool>
typedef pair<int,int> pll;
const int N=2e5+10;
const int inf=1e18;
const int mod=998244353;
void solve(){
int n;
cin>>n;
vi a(n+10);
int isame=0;
bool f=false;
for(int i=0;i<n;i++){
cin>>a[i];
if(i==0) isame=a[i];
else{
if(a[i]!=isame) f=true;
}
}
if(!f){
if(isame==0) cout<<"0\n";
else cout<<n+1<<"\n";
return;
}
int x=(a[1]-a[0]+n)%n;
int ans=x+(a[0]!=0);
for(int i=0;i<n;i++){
if( (a[(i+1)%n] - a[i%n]+n) %n != x) ans=-1;
}
cout<<ans<<"\n";
}
signed main() {
vcoistnt
cout<<fixed<<setprecision(2);
int _=1;
// cin>>_;
while(_--) solve();
return 0;
}
E. Merge the Rectangles
思路
刚开始的思路便是我们遇到一条能合并的边便将其合并,之后发现这并不可行
观察例子我们发现对于一个合法的图像,即如果一个矩形最终能合并的话那么这个矩形内部必然存在至少一条能够贯穿此矩形的线,这条线能够将此矩形分为两个小矩形
那么我们递归暴力搜索一下就行,因为是01那么我们可以用前缀和来判断这条线是否贯穿
代码
#include<bits/stdc++.h>
using namespace std;
#define vcoistnt ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);
#define int long long
#define vi vector<int>
#define vb vector<bool>
typedef pair<int,int> pll;
const int N=2e5+10;
const int inf=1e18;
const int mod=998244353;
vector<vi> x(1505,vi(1505));
vector<vi> y(1505,vi(1505));
bool dfs(int x1,int y1,int x2,int y2){
int sum=0;
for(int i=x1+1;i<x2;i++){
if(y[i][y2-1]-y[i][y1-1]==y2-y1){
return dfs(x1,y1,i,y2) && dfs(i,y1,x2,y2);
}
sum+=y[i][y2-1]-y[i][y1-1];
}
for(int i=y1+1;i<y2;i++){
if(x[x2-1][i]-x[x1-1][i]==x2-x1){
return dfs(x1,y1,x2,i)&&dfs(x1,i,x2,y2);
}
sum+=x[x2-1][i]-x[x1-1][i];
}
if(!sum) return true;
return false;
}
void solve(){
int n,m;
cin>>n>>m;
for(int i=2;i<=n;i++){
for(int j=1;j<=m;j++){
char c;cin>>c;
y[i][j]+=(c-'0');
y[i][j]+=y[i][j-1];
}
}
for(int i=1;i<=n;i++){
for(int j=2;j<=m;j++){
char c;cin>>c;
x[i][j]+=(c-'0');
x[i][j]+=x[i-1][j];
}
}
if(dfs(1,1,n+1,m+1)) cout<<"YES\n";
else cout<<"NO\n";
}
signed main() {
vcoistnt
cout<<fixed<<setprecision(2);
int _=1;
// cin>>_;
while(_--) solve();
return 0;
}