P6154 游走
做法很简单,一个记忆化搜索。
两个关键点:
1.深搜记录路径条数f[x]=(f[x]+f[y])%mod
2.回溯中记录以x为起点的路径长度g[x]=(g[x]+f[y]+g[y])%mod
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=7e5+10;
const int mod=998244353;
int n,m,cnt,tmp,ans;
int tot,to[N],nxt[N],head[N];
int f[N],g[N];
void add(int x,int y) {
to[++tot]=y;
nxt[tot]=head[x];
head[x]=tot;
}
void dfs(int x) {
if(f[x])
return;
f[x]=1;
for(int i=head[x]; i; i=nxt[i])
{
int y=to[i];
dfs(y);
cout<<f[x]<<" "<<f[y]<<endl;
f[x]=(f[x]+f[y])%mod;
g[x]=(g[x]+f[y]+g[y])%mod; //路径长度
}
}
int qpow(int a,int b) {
int ret=1;
while(b) {
if(b&1)
ret=(ret*a)%mod;
b>>=1;
a=(a*a)%mod;
}
return ret%mod;
}
signed main()
{
scanf("%lld%lld",&n,&m);
for(int i=1; i<=m; i++) {
int x,y;
scanf("%lld%lld",&x,&y);
add(x,y);
}
for(int i=1; i<=n; i++)
if(!f[i])dfs(i);
for(int i=1; i<=n; i++) {
cnt=(cnt+f[i])%mod; //以i为起点的路径条数
tmp=(tmp+g[i])%mod; //路径长度
//cout<<f[i]<<endl;
}
//cout<<tmp<< " "<<cnt<<endl;
ans=(tmp%mod*qpow(cnt,mod-2)%mod)%mod;
printf("%lld\n",ans);
return 0;
}
矩阵构造题
#include <iostream>
using namespace std;
int n,m;
char a[505][505];
char a1[505][505],a2[505][505];
int main()
{
cin>>n>>m;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
cin>>a[i][j],a1[i][j]=a[i][j],a2[i][j]=a[i][j];
//cout<<endl;
for(int i=2;i<=n-1;i++)
{
if(i%2)
{
for(int j=2;j<=m-1;j++)
a1[i][j]='1';
}
else
{
for(int j=2;j<=m-1;j++)
a2[i][j]='1';
}
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
if(j==1)
a1[i][j]='1';
cout<<a1[i][j];
}
cout<<endl;
}
//cout<<endl;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
if(j==m)
a2[i][j]='1';
cout<<a2[i][j];
}
cout<<endl;
}
return 0;
}
二维费用背包问题
#include <bits/stdc++.h>
#define ll long long
using namespace std;
int n,H,S;
ll f[305][305];
int main()
{
cin>>n>>H>>S;
H--;
for(int t=1;t<=n;t++)
{
int h,s,w;
cin>>h>>s>>w;
for(int i=H;i>=h;i--)
{
for(int j=S;j>=0;j--)
{
if(j-s>=0)
f[i][j]=max(f[i][j],f[i-h][j-s]+w);
else if(i-h+(j-s)>=0)
f[i][j]=max(f[i][j],f[i-h+(j-s)][0]+w);
}
}
}
cout<<f[H][S]<<endl;
return 0;
}
几何卡精度题
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int inf=0x3f3f3f3f;
double eps=1e-8;
double pi=3.14159265358979323846264338327950288419716;
ll n;
double R,r;
int main()
{
scanf("%lld%lf%lf",&n,&R,&r);
if(n==1&&r<=R)
{
printf("YES\n");
return 0;
}
else if(n==2&&r<=R/2)
{
printf("YES\n");
return 0;
}
double d=pi/n;
double dis=r/sin(d)+r;
//cout<<dis<<endl;
if(dis-R<eps)
printf("YES\n");
else
printf("NO\n");
return 0;
}