A DFS搜索
设置匹配量匹配
通过前一个做标记来完成查找 复杂度O(NT)
#include<bits/stdc++.h>
#define int long long
#define all(x) x.begin(),x.end()
#define rall(x) x.rbegin(),x.rend()
#define pb push_back
#define pii pair<int,int>
using namespace std;
inline int read(){
int a=0;int b=1;char c=getchar();
while(c<48||c>57){if(c=='-')b=-1;c=getchar();}
while(c<=57&&c>=48){a*=10;a+=c-48;c=getchar();}return a*b;
}
void solve(){
int n=read();
string s;
cin>>s;
int ans1=-1,ans2=-1;
for(int i=0;i<n;i++){
if(ans1==-1&&s[i]=='D')ans1=i;
if(ans1!=-1&&s[ans1]=='D'&&s[i]=='F')ans1=i;
if(ans1!=-1&&s[ans1]=='F'&&s[i]=='S')ans1=i;
if(ans2==-1&&s[i]=='d')ans2=i;
if(ans2!=-1&&s[ans2]=='d'&&s[i]=='f')ans2=i;
if(ans2!=-1&&s[ans2]=='f'&&s[i]=='s')ans2=i;
}
if(s[ans1]=='S')ans1=1;else ans1=0;
if(s[ans2]=='s')ans2=1;else ans2=0;
cout<<ans1<<" "<<ans2<<endl;
}
signed main(){
int _=1;
_=read();
while(_--)solve();
}
M 牛客老粉才知道的秘密
根据题意看出 m%6的关系来判断是否乘二
#include<bits/stdc++.h>
#define int long long
#define all(x) x.begin(),x.end()
#define rall(x) x.rbegin(),x.rend()
#define pb push_back
#define pii pair<int,int>
using namespace std;
inline int read(){
int a=0;int b=1;char c=getchar();
while(c<48||c>57){if(c=='-')b=-1;c=getchar();}
while(c<=57&&c>=48){a*=10;a+=c-48;c=getchar();}return a*b;
}
void solve(){
int n=read();
int ans=n/6;
if(n%6!=0)ans*=2;
cout<<ans<<endl;
}
signed main(){
int _=1;
_=read();
while(_--)solve();
}
E 本题又主要考察了贪心
直接DFS爆搜
做题时发现的问题 多元搜索时回归后忘记删除标记
#include<bits/stdc++.h>
#define int long long
#define all(x) x.begin(),x.end()
#define rall(x) x.rbegin(),x.rend()
#define pb push_back
#define pii pair<int,int>
using namespace std;
inline int read(){
int a=0;int b=1;char c=getchar();
while(c<48||c>57){if(c=='-')b=-1;c=getchar();}
while(c<=57&&c>=48){a*=10;a+=c-48;c=getchar();}return a*b;
}
struct node{
int id,x;
};
bool cmp(node a,node b){
if(a.x==b.x)return a.id<b.id;
return a.x>b.x;
}
int n,m,mc;
int a[105],u[105],v[105];
node b[105];
void dfs(int dep){
if(dep==m){
for(int i=1;i<=n;i++)b[i].id=i;
for(int i=1;i<=n;i++)b[i].x=a[i];
sort(b+1,b+n+1,cmp);
for(int i=1;i<=n;i++){
if(b[i].id==1){
mc=min(mc,i);
return;
}
}
}
a[u[dep]]+=3;
dfs(dep+1);
a[u[dep]]-=3;
a[v[dep]]+=3;
dfs(dep+1);
a[u[dep]]+=1;
a[v[dep]]-=2;
dfs(dep+1);
a[u[dep]]--;
a[v[dep]]--;
}
void solve(){
n=read(),m=read();
mc=n;
for(int i=1;i<=n;i++)a[i]=read();
for(int i=0;i<m;i++)u[i]=read(),v[i]=read();
dfs(0);
cout<<mc<<endl;
}
signed main(){
int _=1;
_=read();
while(_--)solve();
}
B 关鸡
通过左边两团火和右边两团火的方式来和特判(1,-1),(1,1),(2,0)之间的关系
比赛时写了一堆屎山代码导致逻辑不清
以后需要注意代码简洁
代码参考jiangly
#include<bits/stdc++.h>
#define int long long
#define all(x) x.begin(),x.end()
#define rall(x) x.rbegin(),x.rend()
#define pb push_back
#define pii pair<int,int>
using namespace std;
inline int read(){
int a=0;int b=1;char c=getchar();
while(c<48||c>57){if(c=='-')b=-1;c=getchar();}
while(c<=57&&c>=48){a*=10;a+=c-48;c=getchar();}return a*b;
}
void solve(){
int n=read();
int left1=0,left2=0,right1=0,right2=0;
set<pii>s;
for(int i=1;i<=n;i++){
int r=read(),c=read();
s.emplace(r,c);
if(c<=0)left1=1;
if(c>=0)right1=1;
}
for(auto [r,c]:s){
if(!c)continue;
if(s.count({r^3,c})||s.count({r^3,c+(c>0?-1:1)})){
if(c<0)left2=1;
else right2=1;
}
}
int ans=4-right2-right1-left1-left2;
int res=3-s.count({1,1})-s.count({1,-1})-s.count({2,0});
ans=min(ans,res);
cout<<ans<<endl;
}
signed main(){
int _=1;
_=read();
while(_--)solve();
}
C 按闹分配
对所有人做前缀和
由题意得 所处的位置为m/tc向下取整
#include<bits/stdc++.h>
#define int long long
#define all(x) x.begin(),x.end()
#define rall(x) x.rbegin(),x.rend()
#define pb push_back
#define pii pair<int,int>
using namespace std;
inline int read(){
int a=0;int b=1;char c=getchar();
while(c<48||c>57){if(c=='-')b=-1;c=getchar();}
while(c<=57&&c>=48){a*=10;a+=c-48;c=getchar();}return a*b;
}
void solve(){
int n=read(),q=read(),c=read();
vector<int>a(n),sum(n,0);
for(int i=0;i<n;i++)a[i]=read();
sort(all(a));
sum[0]=a[0];
for(int i=1;i<n;i++){
sum[i]=sum[i-1]+a[i];
}
while(q--){
int m=read();
int pos=m/c;
pos=min(pos,n-1);
pos=n-pos-1;
cout<<(c*n>m)*sum[pos]+c<<endl;
}
}
signed main(){
int _=1;
// _=read();
while(_--)solve();
}
G why买外卖
对其以a为大小进行排序
不断为折扣加上b因为最后的值肯定大于前面的a必定可以减去折扣
#include<bits/stdc++.h>
#define int long long
#define all(x) x.begin(),x.end()
#define rall(x) x.rbegin(),x.rend()
#define pb push_back
#define pii pair<int,int>
using namespace std;
inline int read(){
int a=0;int b=1;char c=getchar();
while(c<48||c>57){if(c=='-')b=-1;c=getchar();}
while(c<=57&&c>=48){a*=10;a+=c-48;c=getchar();}return a*b;
}
void solve(){
int n=read(),m=read();
vector<pii>a(n);
for(int i=0;i<n;i++){
int x=read(),y=read();
a[i]={x,y};
}
sort(all(a));
int ans=m,sum=0;
for(auto [x,y]:a){
sum+=y;
if(x-sum<=m){
ans=max(ans,sum+m);
}
}
cout<<ans<<endl;
}
signed main(){
int _=1;
_=read();
while(_--
)solve();
}
L 要有光
由题意可得z为0时面积最大 S为3倍最小的三角形即3*w*c
#include<bits/stdc++.h>
#define int long long
#define all(x) x.begin(),x.end()
#define rall(x) x.rbegin(),x.rend()
#define pb push_back
#define pii pair<int,int>
using namespace std;
inline int read(){
int a=0;int b=1;char c=getchar();
while(c<48||c>57){if(c=='-')b=-1;c=getchar();}
while(c<=57&&c>=48){a*=10;a+=c-48;c=getchar();}return a*b;
}
void solve(){
int c=read(),d=read(),h=read(),w=read();
cout<<3*w*c<<endl;
}
signed main(){
int _=1;
_=read();
while(_--)solve();
}
I It's bertrand paradox. Again!
使用随机数生成 来暴力枚举概率
这里使用了x和y的绝对值分布来写
其中发现使用
#define int long long
和mt19937时产生了奇怪的bug
bit-noob的枚举 绝对值在950000左右
void solve(){
int n=100000;
mt19937 rng;
int sum=0;
for(int i=0;i<n;i++){
int x,y,r;
x=rng() % 199 - 99;
y=rng() % 199 - 99;
do{
r=rng() % 100+1;
}
while(x+r>100||x-r<-100||y+r>100||y-r<-100);
sum+=abs(x)+abs(y);
}
cout<<sum<<endl;
}
buaa-noob的枚举 绝对值在750000左右
void solve(){
int n=100000;
mt19937 rng;
int sum=0;
for(int i=0;i<n;i++){
int x,y,r;
do{
x=rng() % 199 - 99;
y=rng() % 199 - 99;
r=rng() % 100+1;
}
while(x+r>100||x-r<-100||y+r>100||y-r<-100);
sum+=abs(x)+abs(y);
}
cout<<sum<<endl;
}
解题代码如下
#include<bits/stdc++.h>
//#define int long long
//#define all(x) x.begin(),x.end()
//#define rall(x) x.rbegin(),x.rend()
//#define pb push_back
//#define pii pair<int,int>
using namespace std;
inline int read(){
int a=0;int b=1;char c=getchar();
while(c<48||c>57){if(c=='-')b=-1;c=getchar();}
while(c<=57&&c>=48){a*=10;a+=c-48;c=getchar();}return a*b;
}
void solve(){
int n=read(),sum=0;
for(int i=1;i<=n;i++){
int x=read(),y=read(),r=read();
sum+=abs(x)+abs(y);
}
if(sum>90*n){
cout<<"bit-noob\n";
}else {
cout<<"buaa-noob\n";
}
}
signed main(){
int _=1;
// _=read();
while(_--)solve();
}
F 鸡数题!
结论题 卡特兰数
结果为{n,n}
公式为
0-M
i^n/(i!)/(m-i)!
代码如下
#include<bits/stdc++.h>
#define int long long
#define all(x) x.begin(),x.end()
#define rall(x) x.rbegin(),x.rend()
#define pb push_back
#define pii pair<int,int>
using namespace std;
inline int read(){
int a=0;int b=1;char c=getchar();
while(c<48||c>57){if(c=='-')b=-1;c=getchar();}
while(c<=57&&c>=48){a*=10;a+=c-48;c=getchar();}return a*b;
}
const int maxn=1e5+10;
const int mod=1e9+7;
int qpow(int x,int y){
int ans=1;
while(y){
if(y&1)ans=ans*x%mod;
x=x*x%mod;
y>>=1;
}
return ans;
}
int f[maxn],inv[maxn];
int getc(int x,int y){
return f[x]*inv[y]%mod*inv[x-y]%mod;
}
void solve(){
int n=read(),m=read();
if(m>n){
cout<<"0\n";
return;
}
vector<int>f(n+1,1),g(n+1,1);
for(int i=1;i<=n;i++){
g[i]=qpow(f[i]=f[i-1]*i%mod,mod-2);
}
int res=0;
for(int i=0;i<=m;i++){
int p=qpow(i,n)*g[i]%mod*g[m-i]%mod;
if((m-i)%2)res+=mod-p;
else res+=p;
res%=mod;
}
cout<<res<<endl;
}
signed main(){
int _=1;
// _=read();
while(_--)solve();
}
H 01背包,但是bit
通过枚举当位是否存在
如果存在则按位取反 然后比该位小的则全部可取比该位大的则不取
代码如下//参考jiangly
#include<bits/stdc++.h>
#define int long long
#define all(x) x.begin(),x.end()
#define rall(x) x.rbegin(),x.rend()
#define pb push_back
#define pii pair<int,int>
using namespace std;
inline int read(){
int a=0;int b=1;char c=getchar();
while(c<48||c>57){if(c=='-')b=-1;c=getchar();}
while(c<=57&&c>=48){a*=10;a+=c-48;c=getchar();}return a*b;
}
const int mod=1e9+7;
void solve(){
int n=read(),m=read();
vector<int>v(n),w(n);
for(int i=0;i<n;i++)v[i]=read(),w[i]=read();
int ans=0;
auto check=[&](int s){
int res=0;
for(int i=0;i<n;i++){
if((s&w[i])==w[i])res+=v[i];
}
ans=max(ans,res);
};
for(int i=29;i>=0;i--){
if(m>>i&1){
check((m^(1<<i))|((1<<i)-1));
}
}
check(m);
cout<<ans<<endl;
}
signed main(){
int _=1;
_=read();
while(_--)solve();
}
大概就补到这里了 感谢观看
2024 2.12