AmazingCounters.com

NOIp2014模拟赛8 河南省选(HAOI 2012)

地址见 BZOJ  2748~2750

 

Description

一个吉他手准备参加一场演出。他不喜欢在演出时始终使用同一个音量,所以他决定每一首歌之前他都要改变一次音量。在演出开始之前,他已经做好了一个列表,里面写着在每首歌开始之前他想要改变的音量是多少。每一次改变音量,他可以选择调高也可以调低。
音量用一个整数描述。输入文件中给定整数beginLevel,代表吉他刚开始的音量,以及整数maxLevel,代表吉他的最大音量。音量不能小于0也不能大于maxLevel。输入文件中还给定了n个整数c1,c2,c3…..cn,表示在第i首歌开始之前吉他手想要改变的音量是多少。
吉他手想以最大的音量演奏最后一首歌,你的任务是找到这个最大音量是多少。

Input

第一行依次为三个整数:n, beginLevel, maxlevel。
第二行依次为n个整数:c1,c2,c3…..cn。

Output

输出演奏最后一首歌的最大音量。如果吉他手无法避免音量低于0或者高于maxLevel,输出-1。

Sample Input

3 5 10               

5 3 7
Sample Output

10
HINT

1<=N<=50,1<=Ci<=Maxlevel 1<=maxlevel<=1000

0<=beginlevel<=maxlevel
音量调节

很水的dp,f[i][j]表示第i首曲子j这个音量是否可以构成

 1 /**************************************************************
 2     Problem: 2748
 3     User: zhangzjd
 4     Language: C++
 5     Result: Accepted
 6     Time:0 ms
 7     Memory:1472 kb
 8 ****************************************************************/
 9  
10 #include<cstdio>
11 #include<cstdlib>
12 #include<iostream>
13 #include<algorithm>
14 using namespace std;
15 #define For(i,n) for(int i=1;i<=n;i++)
16 #define Rep(i,l,r) for(int i=l;i<=r;i++)
17  
18 int A[51],F[51][1001],N,BEGIN,MAX,ans=0;
19  
20 int main()
21 {
22     scanf("%d%d%d",&N,&BEGIN,&MAX);
23     For(i,N) scanf("%d",&A[i]);
24     F[0][BEGIN]=1;
25     For(i,N)
26     {
27         Rep(j,0,MAX)
28           if(F[i-1][j]){
29               if(j+A[i]<=MAX) F[i][j+A[i]]=1;
30               if(j-A[i]>=0)   F[i][j-A[i]]=1;
31           }
32     }
33     For(i,MAX)
34       if(F[N][i]) ans=max(i,ans);
35     if(ans==0)  if(!F[N][0]) ans=-1; 
36     cout<<ans<<endl;
37     return 0;
38 }
Codes

============================================逗比的分割线1==========================================

 [HAOI2012]外星人

Time Limit: 3 Sec  Memory Limit: 128 MB

Description

 

Input

 

Output

输出test行,每行一个整数,表示答案。

Sample Input

1
2
2 2
3 1

Sample Output

3

HINT

Test<=50 Pi<=10^5,1<=Q1<=10^9

 

注意到一个数n被phi之后,每个质因子都会-1,2就被减没了。也就是说如果可以算出每个质因子需要消掉多少2,就可以算出总数。

设f[i]表示i最后会分解出多少个2,那么对于质数,f[i]=f[i-1],否则 f[i*prime[j]] = f[i]+f[prime[j]]。

但是这样对于13这个数据似乎不对? 因为13这个奇数刚开始没有2,所以第一次phi没有算上,最后的ans+1即可

 

 1 #include<set>
 2 #include<queue>
 3 #include<cmath>
 4 #include<cstdio>
 5 #include<cstdlib>
 6 #include<cstring>
 7 #include<iostream>
 8 #include<algorithm>
 9 using namespace std;
10 typedef long long ll;
11 const int N = 100010;
12 #define mp make_pair
13 #define Mod 1000000007
14 #define point pair<int,int>
15 #define For(i,n) for(int i=1;i<=n;i++)
16 #define Rep(i,l,r) for(int i=l;i<=r;i++)
17 #define Down(i,r,l) for(int i=r;i>=l;i--)
18 bool check[N];
19 int n,x,y,prime[N],tot,tests;
20 long long ans,f[N];
21  
22 void PHI(int n){
23     f[1] = 1;
24     for(int i=2;i<=n;i++){
25         if(!check[i]){
26             prime[++tot] = i;
27             f[i]=f[i-1];
28         }
29         for(int j=1;j<=tot;j++){
30             if(prime[j]*i>n) break;
31             check[prime[j]*i] = true;
32             f[i*prime[j]] = f[i] + f[prime[j]];
33             if(i%prime[j]==0)  break;
34         }
35     }
36 } 
37  
38 int main(){
39     PHI(N-10);
40     scanf("%d",&tests);
41     while(tests--){
42         scanf("%d",&n);
43         bool flag=false;
44         For(i,n){
45             scanf("%d%d",&x,&y);
46             if(x==2) flag=true;
47             ans=ans+(long long)(f[x]*y);
48         }
49         if(!flag) ans++;
50         printf("%lld\n",ans);ans=0;
51     }
52     return 0;     
53 }
Codes

 

 

 

===========================================逗比的分割线2==========================================

Description

C国有n座城市,城市之间通过m条单向道路连接。一条路径被称为最短路,当且仅当不存在从它的起点到终点的另外一条路径总长度比它小。两条最短路不同,当且仅当它们包含的道路序列不同。我们需要对每条道路的重要性进行评估,评估方式为计算有多少条不同的最短路经过该道路。现在,这个任务交给了你。

Input

第一行包含两个正整数n、m
接下来m行每行包含三个正整数u、v、w,表示有一条从u到v长度为w的道路

Output

输出应有m行,第i行包含一个数,代表经过第i条道路的最短路的数目对1000000007取模后的结果

Sample Input

4 4

1 2 5

2 3 5

3 4 5

1 4 8

Sample Output

2

3

2

1

HINT

数据规模

30%的数据满足:n≤15、m≤30

60%的数据满足:n≤300、m≤1000

100%的数据满足:n≤1500、m≤5000、w≤10000

Source
Road

dijkstra+heap。用dijkstra是因为如果按dijk算法更新最短路径,那么每次选择的最小的点保存下来即是一个拓扑序,记录从起点到每个点得经过多少条最短路,以及从末尾到每个点的最短路数目,乘法原理即可。

 1 #include<set>
 2 #include<queue>
 3 #include<cmath>
 4 #include<cstdio>
 5 #include<cstdlib>
 6 #include<cstring>
 7 #include<iostream>
 8 #include<algorithm>
 9 const int N=5010;
10 const int M=5010*2;
11 using namespace std;
12 typedef long long ll;
13 #define mp make_pair
14 #define Mod 1000000007
15 #define point pair<int,int>
16 #define For(i,n) for(int i=1;i<=n;i++)
17 #define Rep(i,l,r) for(int i=l;i<=r;i++)
18 #define Down(i,r,l) for(int i=r;i>=l;i--)
19  
20 struct Edge{
21     int t,w;
22     int next;
23 }E[M];
24 bool vis[N];
25 int Es,head[N],dis[N];
26 int n,m,rank[N];
27 long long ans[N],Left[M],Right[M];
28  
29 void Dijk(int s){
30     priority_queue< point,vector<point>,greater<point> > q;
31     q.push(mp(0,s));rank[0]=0;
32     memset(dis,0x777777f,sizeof(dis));dis[s]=0;
33     memset(vis,false,sizeof(vis));memset(Left,0,sizeof(Left));
34     while(!q.empty()){
35         int heads=q.top().second;q.pop();
36         if(!vis[heads]) {
37             rank[++rank[0]]=heads;
38             vis[heads]=true;
39         }
40         for(int p=head[heads];p!=-1;p=E[p].next)
41             if(dis[heads]<dis[E[p].t]-E[p].w){
42                 dis[E[p].t]=dis[heads]+E[p].w;
43                 q.push(mp(dis[E[p].t],E[p].t));
44             }
45     }
46     Left[rank[1]]=1;
47     memset(Right,0,sizeof(Right));
48     For(i,rank[0]) Right[rank[i]]=1;
49     For(i,rank[0])
50         for(int p=head[rank[i]];p!=-1;p=E[p].next)
51           if(dis[E[p].t]==dis[rank[i]]+E[p].w) 
52             Left[E[p].t]=(Left[E[p].t]+Left[rank[i]])%Mod;
53     Down(i,rank[0],1) 
54         for(int p=head[rank[i]];p!=-1;p=E[p].next)
55           if(dis[E[p].t]==dis[rank[i]]+E[p].w) 
56             Right[rank[i]]=(Right[rank[i]]+Right[E[p].t])%Mod;
57     For(i,n)
58         for(int p=head[i];p!=-1;p=E[p].next)
59           if(dis[E[p].t]==dis[i]+E[p].w)
60             ans[p]=(ans[p]+(long long)Left[i]*Right[E[p].t])%Mod;
61 }
62  
63 void Makelist(int s,int t,int w){
64     E[Es].t=t;E[Es].w=w;E[Es].next=head[s];
65     head[s]=Es++;    
66 }
67  
68 void read(int &v){
69     char ch=getchar();int num=0;
70     while(ch>'9'||ch<'0') ch=getchar();
71     while(ch>='0'&&ch<='9'){
72         num=num*10+ch-'0';
73         ch=getchar();
74     }v=num;
75 }
76  
77 int main(){
78     freopen("road.in","r",stdin);
79     freopen("road.out","w",stdout);
80     read(n);read(m);int x,y,w;
81     memset(head,-1,sizeof(head));
82     For(i,m){
83         read(x);read(y);read(w);
84         Makelist(x,y,w);
85     }
86     For(i,n) Dijk(i);
87     Rep(i,0,m-1) printf("%lld\n",ans[i]);
88     return 0;
89 }
Codes

 

posted @ 2014-10-26 20:14  ZJDx1998  阅读(267)  评论(0编辑  收藏  举报