数数
【问题描述】
给定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;
}
浙公网安备 33010602011771号