1002 B - Kanade Loves Maze Designing /hdu6986
题目大意
这个题大意就是给你一棵生成树 每个点的颜色不一样 求i到j之间不同颜色的数量
最后用他给你的函数输出答案
由于n<=2e3
直接dfs暴力搜 注意 当进入某个点时 判断这个颜色有没有接触过 若没接触过则ans++
推出某个点是 也要判断 这个颜色数量是不是 1 若是1 则ans--
#include<bits/stdc++.h>
using namespace std;
const int maxn=5e3+10;
typedef long long ll;
int t,n,cnt,head[maxn];
const int mod1=1e9+7;
const ll mod2=1e9+9;
int c[maxn];
int start;
int a[maxn][maxn];
int vis[maxn],visc[maxn];
int tans=0;
struct xy{
int to,next;
}e[maxn*10];
void add(int x,int y)
{
e[++cnt].to=y;
e[cnt].next=head[x];
head[x]=cnt;
}
ll quickpow(ll a,ll b)
{
long long ans=1;
while(b>0)
{
if(b&1)
{
ans*=a;
ans%=mod1;
}
a*=a;//使用自乘来快速幂。
a%=mod1;
b>>=1;
}
return ans;
}
ll quickpow2(ll a,ll b)
{
long long ans=1;
while(b>0)
{
if(b&1)
{
ans*=a;
ans%=mod2;
}
a*=a;//使用自乘来快速幂。
a%=mod2;
b>>=1;
}
return ans;
}
void init()
{
cnt=0;
memset(e,0,sizeof(e));
memset(c,0,sizeof(c));
memset(head,0,sizeof(head));
memset(visc,0,sizeof(visc));
memset(vis,0,sizeof(vis));
}
void dfs(int now)
{
int x=now;
if(vis[now])return ;
vis[now]=1;
if(visc[c[x]]==0)tans++;
visc[c[x]]++;
a[start][now]=tans;
for(int i=head[now];i;i=e[i].next)
{
int y=e[i].to;
dfs(y);
}
if(visc[c[x]]==1)
{
tans--;
}
visc[c[x]]--;
}
int main()
{
//
cin>>t;
//return 0;
while(t--)
{
//cout<<1;
cin>>n;
//cout<<1;
init();
//continue;
for(int i=2;i<=n;i++)
{
int a;
cin>>a;
add(i,a);
add(a,i);
}
for(int i=1;i<=n;i++)cin>>c[i];
for(int i=1;i<=n;i++)
{
memset(visc,0,sizeof(visc));
memset(vis,0,sizeof(vis));
tans=0;
start=i;
dfs(i);
}
ll ans1=0;
ll ans2=0;
ll x1=19560929;
ll x2=19560929;
for(int i=1;i<=n;i++)
{
ans1=0;
ans2=0;
for(int j=1;j<=n;j++)
{
ans1+=a[i][j]%mod1*(quickpow(x1,j-1)%mod1)%mod1;
ans1%=mod1;
ans2+=a[i][j]%mod2*(quickpow2(x1,j-1)%mod2)%mod2;
ans2%=mod2;
}
cout<<ans1<<" "<<ans2<<endl;
}
}
return 0;
}
1008 I - Lawn of the Dead /hdu6992
待补
1009 I - License Plate Recognition /hdu6993
题目大意 给你一个用点阵图表示的车牌号让你输出每个字符的l,r边界
思路
题目保证只有七个字符 并且每个字符之间存在空格 只存一行数据 预处理
如果这一列任意一行有c[j]=‘#’则标记这一列a[j]为1
从右到左计算每个字符的边界 一开始遇见的第一个1为r 之后遇到的第一个0为l-1
这个题在比赛的时候一直wa 不明白怎么回事 后来才发现还有这种类似于川 这种不连贯的情况
但是幸运的是只有第一个字符才会出现这种情况 于是我们计算到第七个字符时开始另外一种计算方式 就是 记录目前为止最靠右的1和最靠左的1为边界 最后sort一下得出正确答案
#include<bits/stdc++.h>
using namespace std;
int t;
const int maxn=310;
int sz[maxn];
struct node{
int l,r;
}ans[maxn];
int main()
{
cin>>t;
int num=0;
while(t--)
{
memset(sz,0,sizeof(sz));
memset(ans,0,sizeof(ans));
for(int i=1;i<=30;i++)
{
string s;
cin>>s;
for(int j=0;j<s.size();j++)
{
if(s[j]=='#')
{
sz[j+1]=1;
}
}
}
int l=0,r=0;
int fl=0;
cout<<"Case #"<<++num<<":"<<endl;
int cnt=0;
for(int i=100;i>=1;i--)
{
if(cnt==6)
{
if(sz[i]==1)
{
l=min(l,i);
r=max(r,i);
}
continue;
}
if(sz[i]==1&&fl==0)
{
r=i;
fl=1;
continue;
}
if(sz[i]==0&&fl==1)
{
l=i+1;
fl=0;
//cout<<l<<" "<<r<<endl;
ans[++cnt].l=l;
ans[cnt].r=r;
l=100;
r=0;
}
}
ans[7].l=l;
ans[7].r=r;
for(int i=7;i>=1;i--)
{
cout<<ans[i].l<<" "<<ans[i].r<<endl;
}
}
return 0;
}