K进制
描述
给定一个K(2<=K<=16)进制数a,判断a是否能被K-1整除。
输入
第一行是一个整数t(1<=t<=50),表示测试点数量。
对于每组数据,第一行一个整数K,表示进制。
第二行一个K进制数,表示a。保证a是合法的K进制数,没有前导0,且只由’0’-‘9’、’A’-‘F’构成。
输出
如果a可以被K-1整除,输出”yes”,否则输出”no”。
样例输入
2
16
2D
10
19
样例输出
yes
no
提示
对于40%的数据,a的长度不超过5。
对于100%的数据,a的长度不超过100000。
解析:
模拟。
代码:
#include <bits/stdc++.h>
using namespace std;
const int Max=100005;
int t,n,m,num[Max],sum;
char ch[Max];
inline int ksm(int a,int b,int mod)
{
int ans=1;
a%=mod;
while(b)
{
if(b&1) ans=(ans*a)%mod;
b>>=1;
a=(a*a)%mod;
}
return ans;
}
inline bool check()
{
sum=0;
for(int i=1;i<=n;i++)
if(ch[i]>='A') num[i]=(ch[i]-'A')+10;
else num[i]=ch[i]-'0';
for(int i=1;i<=n;i++)
sum=(sum+num[i]*ksm(m,n-i,m-1))%(m-1);
return !sum;
}
int main()
{
scanf("%d\n",&t);
while(t--)
{
scanf("%d%s",&m,ch+1);
n=strlen(ch+1);
if(check()) printf("yes\n");
else printf("no\n");
}
return 0;
}
排队
描述
在成都某中学有m个男生与n个女生排队,这个学校的女生比较古怪,从某个位置(包含这个位置)开始往前数,男生的数量超过了女生的数量,女生会感觉不安全,于是会大叫起来,为了构建和谐校园,安排队伍时应该避免这样的情况。请你计算出不会引发尖叫的排队方案的概率。(排队方案不同定义:当且仅当某个某个位置人不一样,如男生A、男生B ,与男生B、男生A ,2个排列是不同方案)
输入
第一行1个整数, 表示测试数据的组数。
每个数据 有两个数 N,M(N个女生,M个男生)
输出
对于每组数据,输出一个实数(保留到小数点后 6 位)
样例输入
3
1 0
0 1
1 1
样例输出
1.000000
0.000000
0.500000
提示
【 Hint】
第一组:只有一个女生,一种方案且可行
第二组:只有1个男生,一种方案且不行
第三组:两种方案 女、男可行,男、女不可行,可行概率0.5
【数据规模】
30%的数据: (测试组数<=10),(0<=N,M<=1000).
100%的数据: (测试组数=9008 ), ( 0<=N,M<=20000 ).
解析:
可以将原问题转化一下,看成是在一个二维平面上行走,女生看向右移动,男生看成向上移动,那么到达(N,M)点且路线又不走到y=x这条直线上方的路线总数就是答案,这个组合问题很经典,方案数为C(M+N,M)-(M+N,M-1),所以可以知道答案就是1-M/(N+1) 。(注意本来因为男生和女生中两两不同要乘n!m!但是可以约掉)。
代码:
#include <bits/stdc++.h>
using namespace std;
int t;
double n,m;
int main()
{
scanf("%d",&t);
while(t--)
{
scanf("%lf%lf",&n,&m);
if(n<m) printf("%.6f\n",0);
else printf("%.6f\n",1-(m/(n+1)));
}
return 0;
}
航班
描述
L因为业务繁忙,经常会到处出差。因为他是航空公司的优质客户,于是某个航空公司给了他一个优惠券。
他可以利用这个优惠券在任何一个国家内的任意城市间免费旅行,当他的路线跨国才会产生费用。L有一个航空公司的价格表与航线。而且每个城市出发都能到所有的城市,2个城市间可能有不止一个航班,一个国家内的2个城市间一定有不同的路线,但是不同国家的城市间只有一条路线。L想知道从每个城市出发到产生费用最多的城市,不过你不能重复在一个航班上飞来飞去产生费用,必须沿最少的费用路线飞行
输入
第一行,两个整数 N,M,表示N 个城市, M 条航线。
接下来 M 行,每行三个整数 a,b,c,表示城市 a,b 之间有一条费用为 c 的航线。
输出
共 N 行,第 i 行为从城市 i 出发到达每个城市额外费用的最大值。
样例输入
6 6
1 4 2
1 2 6
2 5 3
2 3 7
6 3 4
3 1 8
样例输出
4
4
4
6
7
7
提示
【解释】
有四个国家,包含的城市分别为 {1,2,3},{4},{5},{6}。
从城市 1 出发到达城市 6,乘坐(1,3)(3,6)两个航班费用最大,(1,3)在国内为免费航班, (3,6)的费用为 4,所以从 1 出发的最大费用为 4。
【数据规模】
对于 40%的数据 1<=N<=1000,1<=M<=1000
对于 100%的数据 1<=N<=20000,1<=M<=200000
解析:
边-双联通缩点+树形DP。
代码:
#include <bits/stdc++.h>
using namespace std;
const int Max=200100;
int n,m,Index,cnt,tot,size=1;
int num[Max],low[Max],father[Max],p[Max],vis[Max];
int first[Max],f[Max][3],First[Max],ans[Max],son[Max];
struct shu{int to,next,len;};
shu edge[Max<<1],Edge[Max<<1];
inline int get_int()
{
int x=0,f=1;
char c;
for(c=getchar();(!isdigit(c))&&(c!='-');c=getchar());
if(c=='-') f=-1,c=getchar();
for(;isdigit(c);c=getchar()) x=(x<<3)+(x<<1)+c-'0';
return x*f;
}
inline void print(int x)
{
if(x<0) x=-x,putchar('-');
if(x>9) print(x/10);
putchar('0'+x%10);
}
inline void build(int x,int y,int z)
{
edge[++size].next=first[x];
first[x]=size;
edge[size].to=y,edge[size].len=z;
}
inline void Build(int x,int y,int z)
{
Edge[++size].next=First[x];
First[x]=size;
Edge[size].to=y,Edge[size].len=z;
}
inline void tarjan(int point,int v)
{
num[point]=low[point]=++Index;
p[++tot]=point;
for(int u=first[point];u;u=edge[u].next)
{
int to=edge[u].to;
if((u^1)==v) continue;
if(!num[to]) tarjan(to,u),low[point]=min(low[point],low[to]);
else low[point]=min(low[point],num[to]);
}
if(low[point]==num[point])
{
cnt++;
while(1)
{
int x=p[tot--];
father[x]=cnt;
if(x==point) break;
}
}
}
inline void rebuild()
{
size=0;
for(int i=1;i<=n;i++)
for(int u=first[i];u;u=edge[u].next)
if(father[i]!=father[edge[u].to]) Build(father[i],father[edge[u].to],edge[u].len);
}
inline void dfs1(int point)
{
vis[point]=1;
for(int u=First[point];u;u=Edge[u].next)
{
int to=Edge[u].to;
if(vis[to]) continue;
dfs1(to);
if(f[to][0]+Edge[u].len>f[point][0])
son[point]=to,f[point][1]=f[point][0],f[point][0]=f[to][0]+Edge[u].len;
else f[point][1]=max(f[point][1],f[to][0]+Edge[u].len);
}
}
inline void dfs2(int point)
{
vis[point]=1;
for(int u=First[point];u;u=Edge[u].next)
{
int to=Edge[u].to;
if(vis[to]) continue;
if(to==son[point]) f[to][2]=max(f[point][2],f[point][1])+Edge[u].len;
else f[to][2]=max(f[point][2],f[point][0])+Edge[u].len;
dfs2(to);
}
}
inline int mx(int x,int y){return x<y?y:x;}
int main()
{
n=get_int(),m=get_int();
for(int i=1;i<=m;i++)
{
int x=get_int(),y=get_int(),z=get_int();
build(x,y,z),build(y,x,z);
}
for(int i=1;i<=n;i++) if(!num[i]) tarjan(i,0);
rebuild();
dfs1(1);
memset(vis,0,sizeof(vis));
dfs2(1);
for(int i=1;i<=cnt;i++) ans[i]=mx(f[i][0],f[i][2]);
for(int i=1;i<=n;i++) print(ans[father[i]]),putchar('\n');
return 0;
}