题目链接
A、拯救咕咕咕之史莱姆
做法:dp预处理第六天能减少的血量即可。
dp1[i]记录第i天大洞的个数,dp[i]记录第i天产生的小洞数量,f[i]记录第i天所有洞的数量
f[i]=f[i-1]+dp1[i-1]//前一天大洞dp1产生的小洞
if(i-3>=1)dp1[i]+=dp[i-3];//第四天变成大洞
dp[i]=dp1[i-1]前一天大洞都产生小洞
#include<bits/stdc++.h>
#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 mem(a,x) memset(a,x,sizeof(a))
#define pb push_back
#define pi pair<int, int>
#define mk make_pair
using namespace std;
typedef long long ll;
ll gcd(ll a,ll b) { return b?gcd(b,a%b):a;}
ll f[100],dp[100],dp1[100];
int main()
{
ll ans=3;
f[1]=1;
dp1[1]=1;
for(int i=2;i<=6;++i){
dp1[i]=dp1[i-1];//大洞
if(i-3>=1)dp1[i]+=dp[i-3];//第四天
f[i]=f[i-1]+dp1[i];
dp[i]=dp1[i-1];//小洞产生
//printf("i:%d dp1:%lld dp:%lld f:%lld\n",i,dp1[i],dp[i],f[i]);
ans+=3*f[i];
}
ll n;
while(~scanf("%lld",&n)&&n){
//printf("n:%lld\n",n);
if(n<=ans) puts("AOLIGEI!");
else puts("DAAAAAMN!");
}
}
B-烦人的依赖
简单的字典序排序后再拓扑排序
#include<bits/stdc++.h>
#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 mem(a,x) memset(a,x,sizeof(a))
#define pb push_back
#define pi pair<int, int>
#define mk make_pair
using namespace std;
typedef long long ll;
ll gcd(ll a,ll b) { return b?gcd(b,a%b):a;}
const int N=3e4+10;
vector<int>G[N];
map<string,int>mp;
int n,m,du[N];
string a[N];
void bfs()
{
vector<int>ans;
priority_queue<int,vector<int>,greater<int> >que;
rep(i,1,n) if(!du[i]) que.push(i);
while(que.size()){
int u=que.top();que.pop();
ans.push_back(u);
for(int v:G[u]){
du[v]--;
if(du[v]==0){
que.push(v);
}
}
}
if(ans.size()==n){
for(int v:ans) cout<<a[v]<<endl;
}
else puts("Impossible");
}
bool cmp(string s,string t)
{
return s<t;
}
int main()
{
int cas=0;
int _;cin>>_;while(_--)
{
scanf("%d%d",&n,&m);
mp.clear();
rep(i,1,n) cin>>a[i];
sort(a+1,a+1+n);
rep(i,1,n) mp[a[i]]=i;
rep(i,1,m)
{
char s[15],t[15];
scanf("%s%s",s,t);
int u=mp[s],v=mp[t];
du[v]++;
G[u].push_back(v);
}
printf("Case #%d:\n",++cas);
bfs();
rep(i,1,n){
G[i].clear();
du[i]=0;
}
}
}
C-异或生成树
做法:这题脑子蠢了,其实很简单的,dp[i][j]代表i节点为根时子树异或能到达j的方案数。
dp[u][i^j]=dp[u][i]&&dp[v][j]
#include<bits/stdc++.h>
#define mp make_pair
#define pb push_back
#define ll long long
#define fi first
#define se second
#define inf 0x3f3f3f3f
#define mod 1e9+7
#define mo 998244353
#define io std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
using namespace std;
const int manx=1e6+5;
const int N=8e3+5;
bool dp[300][300],a[300];
ll col[300];
vector<ll>g[300];
void dfs(ll u,ll pre){
dp[u][col[u]]=1;
for(auto v: g[u]){
if(v==pre) continue;
dfs(v,u);
for(int i=0;i<=127;i++) a[i]=dp[u][i];
for(int i=0;i<=127;i++)
for(int j=0;j<=127;j++)
if(a[i]&&dp[v][j])
dp[u][i^j]=1;
}
}
int main(){
ll n; cin>>n;
for(int i=1;i<=n;i++) cin>>col[i];
for(int i=1;i<n;i++){
ll u,v; cin>>u>>v;
g[u].pb(v); g[v].pb(u);
}
dfs(1,0);
ll ans=0;
for(int i=1;i<=n;i++)
for(ll j=1;j<=127;j++)
if(dp[i][j]) ans=max(ans,j);
cout<<ans<<endl;
return 0;
}
E-无敌阿姨
简单模拟题
#include<bits/stdc++.h>
#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 mem(a,x) memset(a,x,sizeof(a))
#define pb push_back
#define pi pair<int, int>
#define mk make_pair
using namespace std;
typedef long long ll;
ll gcd(ll a,ll b) { return b?gcd(b,a%b):a;}
const int N=1e2+10;
int a[N],n,m,k;
int main()
{
int _;cin>>_;while(_--)
{
scanf("%d%d%d",&n,&m,&k);
rep(i,1,n){
scanf("%d",&a[i]);
}
int ans=1,now=m;
int l=1,r=n;
while(l<=n)
{
//printf("l%d now:%d\n",l,now);
int d=min(now,a[l]);
a[l]-=d;
now-=d;
if(a[l]==0){
if(l+1>n) break;
++l;
if(now>k){
now-=k;
}
else {
ans++;
now=m;
}
}
else{
now=m;
ans++;
}
}
printf("%d\n",ans);
}
}
G-校车
做法:对站点离散化后再差分求期间公交车人数最大值
#pragma GCC optimize(2)
#include<bits/stdc++.h>
#define ll long long
#define register int int
#define maxn 1005
#define inf 1e9
#define pb push_back
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define per(i,a,b) for(int i=a;i>=b;i--)
using namespace std;
inline int read()
{
int x=0,w=1; char c=getchar();
while(c<'0'||c>'9') {if(c=='-') w=-1; c=getchar();}
while(c<='9'&&c>='0') {x=(x<<1)+(x<<3)+c-'0'; c=getchar();}
return w==1?x:-x;
}
const int N=1e5+10;
int X[3*N],len,n,Y[2*N],len1,sum[3*N],l[N],r[N];
int get(int x)
{
return lower_bound(X+1,X+1+len,x)-X;
}
int main()
{
int _=read();while(_--)
{
len=0;
n=read();
rep(i,1,n)
{
l[i]=read(),r[i]=read();
X[++len]=l[i];
X[++len]=r[i];
}
sort(X+1,X+1+len);
len=unique(X+1,X+1+len)-X-1;
rep(i,1,len+5) sum[i]=0;
rep(i,1,n){
l[i]=get(l[i]);
r[i]=get(r[i]);
sum[l[i]]++;
sum[r[i]]--;
}
int ans=0;
rep(i,1,len+1){
sum[i]+=sum[i-1];
ans=max(ans,sum[i]);
}
//printf("%d\n",ans);
printf("%d %d\n",len,ans);
}
}
H-中位因数
做法:nlog(n)枚举整除的筛法,原来这种筛法还有这性质,学到了学到了
#include<bits/stdc++.h>
#define LL long long
#define PB push_back
using namespace std;
const int N=1e6+10,mod=1e9+7;
int n,m;
int a[N];
LL s[N];
int main()
{
for(int i=1;i<N;i++){
for(int j=i;j<N;j+=i){
if(1ll*i*i<=j)a[j]=i;
}
}
for(int i=1;i<N;i++){
s[i]=s[i-1]+(a[i]+i/a[i])/2;
s[i]%=mod;
}
int t;
cin>>t;
while(t--){
scanf("%d",&n);
printf("%lld\n",s[n]);
}
return 0;
}