数数
【问题描述】
给定n,m,k都是小于等于10001的正整数,输出给定的n个数中,其m次幂能被k整除的数的个数。
【输入格式】
有两行组成,第一行是三个整数n,m,k
第二行是n个正整数 都不超过10001
【输出格式】
输出满足条件的数的个数
【样例输入】count.in
3 2 50
9 10 11
【样例输出】count.out
1
#include <cstdio> const int prime[25]={2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97}; int n,m,k; int c[25]; int main(){ freopen("count.in","r",stdin); freopen("count.out","w",stdout); scanf("%d%d%d",&n,&m,&k); int j=k; for (int i=0;i<25;i++){ while ((j % prime[i])==0){ j/=prime[i]; c[i]++; } } if (j!=1) k=j;else k=1; for (int i=0;i<25;i++){ if (c[i] % m==0) c[i]/=m;else c[i]=c[i]/m+1; for (int j=1;j<=c[i];j++) k*=prime[i]; } m=0; for (int i=1;i<=n;i++){ int x; scanf("%d",&x); if (!(x % k)) m++; } printf("%d\n",m); return 0; }
最长链
【问题描述】
给定一棵有N个节点的树,求每个节点到其他节点的最大距离
【输入格式】
输入第一行是一个自然数 N (N<=10000), 接下来 (N-1) 行描述:
第i行包含两个自然数 , 表示编号为i的节点连接到的节点编号和这条网线的长度..距离总长不会超过10^9. 每行中的两个数字用空格隔开.
【输出格式】
输出包含N行. 第i行表示对于离编号为i的节点最远的节点与该节点的距离Si(1<=i<=N).
【样例输入】length.in
3
1 1
1 2
【样例输出】length.out
2
3
3
【数据范围】
30% N<=100
100%N<=10000
#include <cstdio> #include <cstring> #include <iostream> #define INF 214748364 struct edge{ int x,w,next; }e[20010],e2[20010]; int tot2,tot; int n; bool v[20010]; int k2[20010]; int fa[20010]; int w[20010]; int k[20010]; int f[20010][3]; int max(int a,int b){return a>b?a:b;} void add2(int x,int y,int z){ e2[++tot2].x=y; e2[tot2].w=z; e2[tot2].next=k2[x]; k2[x]=tot2; } void add(int x,int y,int z){ e[++tot].x=y; e[tot].w=z; e[tot].next=k[x]; k[x]=tot; } void build(int x){ v[x]=true; for (int t=k2[x];t;t=e2[t].next){ if (!v[e2[t].x]){ add(x,e2[t].x,e2[t].w); fa[e2[t].x]=x; w[e2[t].x]=e2[t].w; build(e2[t].x); } } } void dp1(int x){ for (int t=k[x];t;t=e[t].next){ dp1(e[t].x); if (f[x][1]<f[e[t].x][1]+e[t].w){ f[x][2]=f[x][1]; f[x][1]=f[e[t].x][1]+e[t].w; }else if (f[x][2]<f[e[t].x][1]+e[t].w){ f[x][2]=f[e[t].x][1]+e[t].w; } } } void dp2(int x){ if (fa[x]!=-1){ if (f[fa[x]][1]==f[x][1]+w[x]) f[x][0]=max(f[fa[x]][0],f[fa[x]][2])+w[x]; else f[x][0]=max(f[fa[x]][0],f[fa[x]][1])+w[x]; } for (int t=k[x];t;t=e[t].next){ dp2(e[t].x); } } int main(){ freopen("length.in","r",stdin); freopen("length.out","w",stdout); scanf("%d",&n); for (int i=2;i<=n;i++){ int x,y; scanf("%d%d",&x,&y); add2(i,x,y); add2(x,i,y); } memset(fa,255,sizeof(fa)); build(1); dp1(1); dp2(1); for (int i=1;i<=n;i++){ int ans=max(f[i][0],f[i][1]); printf("%d\n",ans); } return 0; }
水站
【问题描述】
已知有一个N 层的水站 :
Wi表示未操作之前第i层的已有水量;
Li 表示第i个水站能够维持或者储存的水的重量;
Pi 表示在第i层进行减压放水操作所需的费用.
被压减放水层所储存的所有水都将流向下一层.
如果第 i层的水量比Li大,则这一层也会(自动)减压(不需要任何费用).
现在想要使最后一层减压(第N级) ,求最少的花费.
这个任务现在交给了你。
【输入格式】
每个输入的第一行包含一个自然数N (1<=N<=15000).
接下来N行每行包含 3 个数 Wi, Li, Pi (0<=Wi,Li,Pi<=15000).
【输出格式】
第一行输出所需的最小费用
第二行若干个整数,从小到大输出必须减压的层的编号。
【样例输入】station.in
3
1000 1000 1
0 1000 2
2 10 100
【样例输出】station.out
3
1 2
Hint:给第一层和第二层减压
【数据范围】
30% N<=5000
100%N<=15000
#include <iostream> #include <cstdio> #include <queue> #include <cstdlib> #include <cstring> #define INF 214748364 using namespace std; int n; int w[15100],l[15100],p[15100]; int sum[15100]; int cost; int ans=INF,ansi; typedef struct Heap{ bool operator <(Heap T)const{ return T.need<need; } int need; int id; }Heap; priority_queue<Heap>Q; int main(){ freopen("station.in","r",stdin); freopen("station.out","w",stdout); scanf("%d",&n); for (int i=1;i<=n;i++){ scanf("%d%d%d",&w[i],&l[i],&p[i]); } for (int i=n;i>0;i--) sum[i]=sum[i+1]+w[i]; for (int i=n;i>0;i--){ cost+=p[i]; while (!Q.empty() && sum[i]-Q.top().need>0){ cost-=p[Q.top().id]; Q.pop(); } Heap t; t.id=i; t.need=l[i]-w[i]+sum[i]; Q.push(t); if (ans>cost){ ans=cost; ansi=i; } } printf("%d\n",ans); cost=0; for (int i=ansi;i<=n;i++){ cost+=w[i]; if (cost<=l[i]){ printf("%d ",i); } } return 0; }
聚会
【问题描述】
小S想要从某地出发去同学k的家中参加一个party,但要有去有回。他想让所用的时间尽量的短。但他又想知道从不同的点出发,来回的最短时间中最长的时间是多少,
这个任务就交给了你。
【输入格式】
第一行三个正整数n,m,k(n是节点个数,m是有向边的条数,k是参加聚会的地点编号)( 1 ≤ N ≤ 1000 ,1 ≤ M ≤ 100,000)
第二行..m+1行每行3个整数x,y,w 代表从x到y需要花w的时间(1 ≤ w≤ 100)
【输出格式】
输出从不同的节点出发的最短时间中最长的时间。
【样例输入】party.in
4 8 2
1 2 4
1 3 2
1 4 7
2 1 1
2 3 5
3 1 2
3 4 4
4 2 3
【样例输出】party.out
10
#include <cstdio> #include <cstring> #define INF 2147483647 int n,m,K; struct node{ int x,w,next; }e[101000],e2[101000]; int k[1100]; int k2[1100]; int tot,tot2; int d[1100]; int d2[1100]; bool v[1100]; int f[1000000]; int max(int a,int b){return a>b?a:b;} void add(int x,int y,int z){ e[++tot].x=y; e[tot].w=z; e[tot].next=k[x]; k[x]=tot; } void add2(int x,int y,int z){ e2[++tot2].x=y; e2[tot2].w=z; e2[tot2].next=k2[x]; k2[x]=tot2; } void SPFA(){ memset(v,0,sizeof(v)); memset(d,8,sizeof(d)); d[K]=0; v[K]=true; int head=0,tail=1; f[tail]=K; while (head<tail){ int x=f[++head]; v[x]=false; for (int t=k[x];t;t=e[t].next){ if (d[e[t].x]>d[x]+e[t].w){ d[e[t].x]=d[x]+e[t].w; if (!v[e[t].x]){ v[e[t].x]=true; f[++tail]=e[t].x; } } } } } void SPFA2(){ memset(v,0,sizeof(v)); memset(d2,8,sizeof(d2)); d2[K]=0; v[K]=true; int head=0,tail=1; f[tail]=K; while (head<tail){ int x=f[++head]; v[x]=false; for (int t=k2[x];t;t=e2[t].next){ if (d2[e2[t].x]>d2[x]+e2[t].w){ d2[e2[t].x]=d2[x]+e2[t].w; if (!v[e2[t].x]){ v[e2[t].x]=true; f[++tail]=e2[t].x; } } } } } int main(){ freopen("party.in","r",stdin); freopen("party.out","w",stdout); scanf("%d%d%d",&n,&m,&K); for (int i=1;i<=m;i++){ int x,y,z; scanf("%d%d%d",&x,&y,&z); add(x,y,z); add2(y,x,z); } SPFA(); SPFA2(); int ans=0; for (int i=1;i<=n;i++){ if (d[i]+d2[i]<10000000){ ans=max(ans,d[i]+d2[i]); } } printf("%d\n",ans); return 0; }