【noip 2016】提高组

D1T1.玩具谜题

题目链接

直接模拟就好了……water。(然而比赛的时候数组开少了一个0)

 1 #include<cstdio>
 2 int n,m,a,s,ans;
 3 struct node{char name[12];int dir;}x[100050];
 4 int main()
 5 {
 6     scanf("%d%d",&n,&m);
 7     for(int i=0;i<n;i++)scanf("%d%s",&x[i].dir,x[i].name);
 8     while(m--)
 9     {
10         scanf("%d%d",&a,&s);
11         if(a==x[ans].dir)ans-=s;
12         else ans+=s;
13         if(ans<0)ans+=n;
14         ans%=n;
15     }
16     printf("%s",x[ans].name);
17     return 0;
18 }

D1T2.天天爱跑步

题目链接

因为太菜了,至今不会这道题……先扔题目链接,以后再回来把坑填了(flag

D1T3.换教室

题目链接

最短路+期望dp。

数组dp[i][j][k]代表当前进行到第i个时间段,已经更换了j门课程;若k=0则代表当前时间段不更换教室,k=1则代表当前时间段更换教室。

记得最后再循环一下dp[n][j][k],输出最优解。

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 using namespace std;
 5 const int N=2050;
 6 const double inf=1e15;
 7 int n,m,v,e,a,b,c[N],d[N];
 8 double w,k[N],dp[N][N][2],dis[N][N];
 9 int read()
10 {
11     int x=0,f=1;char c=getchar();
12     while(c<‘0‘||c>‘9‘){if(c==‘-‘)f=-1;c=getchar();}
13     while(c>=‘0‘&&c<=‘9‘){x=x*10+c-‘0‘;c=getchar();}
14     return x*f;
15 }
16 void floyd()
17 {
18     for(int k=1;k<=v;k++)
19         for(int i=1;i<=v;i++)
20             for(int j=1;j<=v;j++)
21                 dis[i][j]=dis[j][i]=min(dis[i][j],dis[i][k]+dis[k][j]);
22 }
23 int main()
24 {
25     n=read();m=read();v=read();e=read();
26     for(int i=1;i<=n;i++)c[i]=read();
27     for(int i=1;i<=n;i++)d[i]=read();
28     for(int i=1;i<=n;i++)scanf("%lf",&k[i]);
29     for(int i=1;i<=v;i++)
30         for(int j=1;j<=v;j++)
31             if(i!=j)dis[i][j]=inf;
32     for(int i=0;i<=n;i++)
33         for(int j=0;j<=m;j++)
34             dp[i][j][0]=dp[i][j][1]=inf;
35     for(int i=1;i<=e;i++)
36         a=read(),b=read(),scanf("%lf",&w),dis[a][b]=dis[b][a]=min(dis[a][b],w);
37     floyd();
38     dp[1][0][0]=0;dp[1][1][1]=0;
39     for(int i=2;i<=n;i++)
40         for(int j=0;j<=m;j++)
41         {
42             if(j==0)dp[i][j][0]=min(dp[i][j][0],dp[i-1][j][0]+dis[c[i-1]][c[i]]);
43             else
44             {
45                 dp[i][j][0]=min(dp[i][j][0],dp[i-1][j][0]+dis[c[i-1]][c[i]]);
46                 dp[i][j][0]=min(dp[i][j][0],dp[i-1][j][1]+dis[d[i-1]][c[i]]*k[i-1]+dis[c[i-1]][c[i]]*(1-k[i-1]));
47                 dp[i][j][1]=min(dp[i][j][1],dp[i-1][j-1][0]+dis[c[i-1]][d[i]]*k[i]+dis[c[i-1]][c[i]]*(1-k[i]));
48                 dp[i][j][1]=min(dp[i][j][1],dp[i-1][j-1][1]+dis[c[i-1]][c[i]]*(1-k[i-1])*(1-k[i])+dis[c[i-1]][d[i]]*(1-k[i-1])*k[i]
49                 +dis[d[i-1]][c[i]]*k[i-1]*(1-k[i])+dis[d[i-1]][d[i]]*k[i-1]*k[i]);
50             }
51         }
52     double ans=inf;
53     for(int i=0;i<=m;i++)
54     {
55         ans=min(ans,dp[n][i][0]);
56         ans=min(ans,dp[n][i][1]);
57     }
58     printf("%.2lf",ans);
59     return 0;
60 }

D2T1.组合数问题

题目链接

杨辉三角打个表,然后前缀和优化优化(get到新姿势

 1 #include<cstdio>
 2 #include<algorithm>
 3 #include<cstring>
 4 using namespace std;
 5 const int N=2005;
 6 long long n,m,t,k,f[N][N],sum[N][N];
 7 long long read()
 8 {
 9     long long x=0,f=1;char c=getchar();
10     while(c<‘0‘||c>‘9‘){if(c==‘-‘)f=-1;c=getchar();}
11     while(c>=‘0‘&&c<=‘9‘){x=x*10+c-‘0‘;c=getchar();}
12     return x*f;
13 }
14 int main()
15 {
16     t=read();k=read();
17     for(int i=0;i<N;i++)f[i][0]=1;
18     for(int i=1;i<N;i++)
19         for(int j=1;j<=i;j++)
20         {
21             f[i][j]=(f[i-1][j]+f[i-1][j-1])%k;
22             if(!f[i][j])sum[i][j]=1;
23             sum[i][j]+=sum[i][j-1];
24         }
25     while(t--)
26     {
27         long long ans=0;
28         n=read();m=read();
29         for(long long i=1;i<=n;i++)
30             ans+=sum[i][min(m,i)];
31         printf("%lld\n",ans);
32     }
33     return 0;
34 }

D2T2.蚯蚓

题目链接

维护三个队列:q1是原数列(先从大到小sort一波),q2是砍完之后的前段,q3是砍完之后的后段(依据题意易得,q2、q3单调递减)。每次从三个队列的队头元素取出最大的一个进行切断操作并在队列中删去它,再将砍完后生成的两个新数分别存入q2、q3。

至于每次操作完增加的长度……直接用时间算就好了?

 1 #include<cstdio>
 2 #include<cmath>
 3 #include<cstring>
 4 #include<algorithm>
 5 using namespace std;
 6 const int N=100050;
 7 const int M=7000050;
 8 double p;
 9 int h1=1,h2=1,t2,h3=1,t3;
10 long long n,m,q,u,v,t;
11 long long q1[N],q2[M],q3[M];
12 long long read()
13 {
14     long long x=0,f=1;char c=getchar();
15     while(c<‘0‘||c>‘9‘){if(c==‘-‘)f=-1;c=getchar();}
16     while(c>=‘0‘&&c<=‘9‘){x=x*10+c-‘0‘;c=getchar();}
17     return x*f;
18 }
19 bool cmp(long long a,long long b){return a>b;}
20 long long get(int tim)
21 {
22     long long x=-0x3f3f3f3f3f3f3f3f;
23     if(h1<=n&&q1[h1]>x)x=q1[h1];
24     if(h2<=t2&&q2[h2]>x)x=q2[h2];
25     if(h3<=t3&&q3[h3]>x)x=q3[h3];
26     if(h1<=n&&x==q1[h1])h1++;
27     else if(h2<=t2&&x==q2[h2])h2++;
28     else h3++;
29     return x+(tim-1)*q;
30 }
31 int main()
32 {
33     n=read();m=read();q=read();u=read();v=read();t=read();p=1.0*u/v;
34     for(int i=1;i<=n;i++)q1[i]=read();
35     sort(q1+1,q1+n+1,cmp);
36     for(int i=1;i<=m;i++)
37     {
38         long long k=get(i);
39         if(i%t==0)printf("%lld ",k);
40         long long k1=floor(k*p),k2=k-k1;
41         q2[++t2]=k1-q*i;q3[++t3]=k2-q*i;//注意-q*i!
42     }
43     printf("\n");
44     for(int i=1;i<=n+m;i++)
45     {
46         long long k=get(m+1);
47         if(i%t==0)printf("%lld ",k);
48     }
49     return 0;
50 }

D3T3.愤怒的小鸟

题目链接

状压dp……注意精度问题。

f[i][j]代表当第i只小猪与第j只小猪配对时,小鸟的飞行轨迹可以消灭的小猪的状态。处理完就先枚举当前状态,然后枚举第一只尚未配对的小猪,再枚举与其配对的小猪,直接dp。

注意:有可能一只小鸟只消灭了一只小猪。

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<cmath>
 4 #include<algorithm>
 5 using namespace std;
 6 int T,n,m,id[20],f[20][20],dp[1<<20];
 7 double a,b,x[20],y[20];
 8 bool pan(double x,double y){return fabs(x-y)<1e-6;}
 9 void solve()
10 {
11     scanf("%d%d",&n,&m);
12     for(int i=1;i<=n;i++)scanf("%lf%lf",&x[i],&y[i]);
13     memset(f,0,sizeof(f));
14     for(int i=1;i<=n;i++)
15         for(int j=i+1;j<=n;j++)
16         {
17             if(pan(x[i],x[j]))continue;
18             a=(y[j]/x[j]-y[i]/x[i])/(x[j]-x[i]);
19             if(a>=0)continue;
20             b=y[i]/x[i]-a*x[i];
21             int t=0;
22             for(int k=1;k<=n;k++)
23                 if(pan(a*x[k]+b,y[k]/x[k]))t+=id[k];
24             f[i][j]=t;
25         }
26     memset(dp,0x3f,sizeof(dp));dp[0]=0;
27     for(int i=0;i<(1<<n);i++)
28         for(int j=1;j<=n;j++)
29         {
30             if(i&id[j])continue;
31             for(int k=j+1;k<=n;k++)
32                 dp[i|f[j][k]]=min(dp[i|f[j][k]],dp[i]+1);
33             dp[i|id[j]]=min(dp[i|id[j]],dp[i]+1);//注意处理一只小鸟只消灭一只小猪的情况!
34         }
35     printf("%d\n",dp[(1<<n)-1]);
36 }
37 int main()
38 {
39     for(int i=1;i<=19;i++)id[i]=1<<(i-1);
40     scanf("%d",&T);
41     while(T--)solve();
42     return 0;
43 }

时间: 2024-08-01 06:36:39

【noip 2016】提高组的相关文章

模拟(玩具谜题NOIP 2016 提高组 Day 1 第一题vijos2003)

描述 小南有一套可爱的玩具小人,它们各有不同的职业. 有一天,这些玩具小人把小南的眼镜藏了起来.小南发现玩具小人们围成了一个圈,它们有的面朝圈内,有的面朝圈外.如下图: 这时singer告诉小南一个谜题:“眼镜藏在我左数第3个玩具小人的右数第1个玩 具小人的左数第2个玩具小人那里.” 小南发现,这个谜题中玩具小人的朝向非常关键,因为朝内和朝外的玩具小人的左右方向是相反的:面朝圈内的玩具小人,它的左边是顺时针方向,右边是逆时针方向:而面向圈外的玩具小人,它的左边是逆时针方向,右边是顺时针方向. 小

noip 2016 提高组试题看法

前几天写的那个纯属搞笑.(额,好吧,其实这个也不怎么正经) 就先说说day2吧: T1:这个东西应该叫做数论吧. 然而我一看到就照着样例在纸上推了大半天(然而还是没有看出来这东西是个杨辉三角) 然后就想干脆先把n≤25的拿了再说(这个爆不了long long) 然后就硬套用那个组合数公式. 再然后,就只拿了35分. T2:我勒个去. 这个东西应该用堆来优化的吧. 然而并不会堆. 然后就切一个遍历一遍把两端都再加进去(虽然我知道这个时间复杂度估计连20都拿不了). 一个估计是正解的东西: 思考一下

noip 2016 提高组总结(不是题解)

小弱鸡杨树辰是第一次参加像noip这样的高大上的比赛,于是他非常,非常,非常激动. 当他第二天考完试后,他正在yy自己的分数:day1T1应该是a掉了,T2写了个30分的暴力,T3也是个40分的暴力,这第一天就能拿到170了,他的心情非常开心,非常非常开心:day2T1应该是50分,T2么,随便拿个25好了,至于T3,呵呵呵呵呵呵呵,爆零就好~我带你去看天荒地老~,咳咳: 这时,一位记者瞄上了他; 记者:"你好这位同学,可以谈一下本次noip的经历么?" ysc:"我么?我可

NOIP 2012 提高组 DAY1 T2 国王游戏

题目描述 恰逢 H 国国庆,国王邀请 n 位大臣来玩一个有奖游戏.首先,他让每个大臣在左.右 手上面分别写下一个整数,国王自己也在左.右手上各写一个整数.然后,让这 n 位大臣排 成一排,国王站在队伍的最前面.排好队后,所有的大臣都会获得国王奖赏的若干金币,每 位大臣获得的金币数分别是:排在该大臣前面的所有人的左手上的数的乘积除以他自己右 手上的数,然后向下取整得到的结果. 国王不希望某一个大臣获得特别多的奖赏,所以他想请你帮他重新安排一下队伍的顺序, 使得获得奖赏最多的大臣,所获奖赏尽可能的少

NOIP 2014 提高组 题解

NOIP 2014 提高组 题解 No 1. 生活大爆炸版石头剪刀布 http://www.luogu.org/problem/show?pid=1328 这是道大水题,我都在想怎么会有人错了,没算法,直接模拟,别读错题. 1 int wn[5][5]={{2,0,1,1,0}, 2 {1,2,0,1,0}, 3 {0,1,2,0,1}, 4 {0,0,1,2,1}, 5 {1,1,0,0,2}}; 6 7 int n,na,nb; 8 int a[222],b[222]; 9 int s1,s

NOIP 2008提高组第三题题解by rLq

啊啊啊啊啊啊今天已经星期三了吗 那么,来一波题解吧 本题地址http://www.luogu.org/problem/show?pid=1006 传纸条 题目描述 小渊和小轩是好朋友也是同班同学,他们在一起总有谈不完的话题.一次素质拓展活动中,班上同学安排做成一个m行n列的矩阵,而小渊和小轩被安排在矩阵对角线的两端,因此,他们就无法直接交谈了.幸运的是,他们可以通过传纸条来进行交流.纸条要经由许多同学传到对方手里,小渊坐在矩阵的左上角,坐标(1,1),小轩坐在矩阵的右下角,坐标(m,n).从小渊

NOIP 2006 提高组 t1 能量项链

题目描述 在Mars星球上,每个Mars人都随身佩带着一串能量项链.在项链上有N颗能量珠.能量珠是一颗有头标记与尾标记的珠子,这些标记对应着某个正整数.并且,对于相邻的两颗珠子,前一颗珠子的尾标记一定等于后一颗珠子的头标记.因为只有这样,通过吸盘(吸盘是Mars人吸收能量的一种器官)的作用,这两颗珠子才能聚合成一颗珠子,同时释放出可以被吸盘吸收的能量.如果前一颗能量珠的头标记为m,尾标记为r,后一颗能量珠的头标记为r,尾标记为n,则聚合后释放的能量为m*r*n(Mars单位),新产生的珠子的头标

扩展欧几里得模板(洛谷1082 同余方程NOIP 2012 提高组 第二天 第一题)

题目描述 求关于 x 的同余方程 ax ≡ 1 (mod b)的最小正整数解. 输入输出格式 输入格式: 输入只有一行,包含两个正整数 a, b,用一个空格隔开. 输出格式: 输出只有一行,包含一个正整数 x0,即最小正整数解.输入数据保证一定有解. 输入输出样例 输入样例#1: 3 10 输出样例#1: 7 说明 [数据范围] 对于 40%的数据,2 ≤b≤ 1,000: 对于 60%的数据,2 ≤b≤ 50,000,000: 对于 100%的数据,2 ≤a, b≤ 2,000,000,000

【NOIP】提高组2016 愤怒的小鸟

[题意]Universal Online Judge [算法]状态压缩型DP [题解]看数据范围大概能猜到是状压了. 根据三点确定一条抛物线,枚举两个点之间的抛物线,再枚举有多少点在抛物线上(压缩为状态c[]),这样预处理出至多n*n/2+n条抛物线.(注意加上只经过一点的抛物线) 然后f[i]表示猪的消灭状态为i的最小步数,转移方程:f[i&c[j]]=min(f[i&c[j]],f[i]+1). #include<cstdio> #include<cstring>

【NOIP】提高组2016 蚯蚓

[题目链接]Universal Online Judge [题解]本题最大的特点在于从大到小切以及切分规则一致,都是切成px和x-px. 由这两个特点很容易得到结论,后切的蚯蚓得到的px一定比先切的蚯蚓得到的px小,后切的蚯蚓得到的x-px一定比先切的蚯蚓得到的x-px小. 所以可以得到三队列做法,将原蚯蚓排序后放入A队列,将每次切分后的px放入B队尾,x-px放入C队尾.每次从ABC三队头取较大者弹出并切分,将切分后的蚯蚓放入BC队尾,整体+q转化为单点-q即可. 注意:UOJ extra t