[总结+题解]NOIP2015模拟题2

// 此博文为迁移而来,写于2015年7月22日,不代表本人现在的观点与看法。原始地址:http://blog.sina.com.cn/s/blog_6022c4720102w72i.html

1、总结

向总表示今天的题目简单些,恩我觉得我又单纯了。今天的分数略低啊,第三题的动规只有10分,第一题的暴力也TLE了一堆,最后就剩下个150分了。

2、题解

T1 坐船问题(TAG:结论题)

简直就是一道结论题啊!这道题不存在什么算法。最开始想到的是二分图匹配,但是过于繁琐,而且已经证出存在反例。首先对于两个对象A和B,如果他们姓相同或者名相同,则将两者之间连一条边,任何相对之间存在姓相同或名相同关系的点,便会组成一个连通块,通过对其中的分析,可以得出其中的结论。具体的我没有做出来,大家可以看看解题报告中的一段话,代码就不上了。

T2 多边形划分问题(TAG:动态规划)

【P.S 标题有误,特此提醒】

一道动态规划题目,核心在于对于多边形的每一个顶点进行编号,根据n边形由n-2个三角形组成的原理,可以设计出状态。

代码:

---------------------------------------------------------------------------------------------------
#include cstdio
#include cstring

#define MAXN 105
#define MOD 100000
#define INF 1<<30

typedef long long arr[MAXN];

long long max(long long a,long long b) { return (a>b)?a:b; }

arr f[MAXN][MAXN],a,s1,s2,s3;
long long n;

void mark(arr &c)
{
        for (int i=1;i<=c[0];i++)
        {
                c[i+1]+=c[i]/MOD;
                c[i]%=MOD;
        }
        while (c[c[0]+1])
        {
                c[0]++;
                c[c[0]+1]+=c[c[0]]/MOD;
                c[c[0]]%=MOD;
        }
}

void multi(long long a1,long long a2,long long a3,arr &s)
{
         memset(s,0,sizeof(s));
         s[0]=s[1]=1;
         for (int i=1;i<=s[0];i++) s[i]*=a1; mark(s);
         for (int i=1;i<=s[0];i++) s[i]*=a2; mark(s);
         for (int i=1;i<=s[0];i++) s[i]*=a3; mark(s);
}

void addVal(arr a,arr b,arr &c)
{
     memset(c,0,sizeof(c));
     c[0]=max(a[0],b[0]);
     for (int i=1;i<=c[0];i++) c[i]=a[i]+b[i];
     mark(c);
}

int check(arr a,arr b)
{
        if (a[0]<b[0]) return 0;
        if (a[0]>b[0]) return 1;
        for (int i=a[0];i>=1;i--)
                if (a[i]
                else if (a[i]>b[i]) return 1;
        return 0; 
}

int main()
{
        freopen("polygon.in","r",stdin);
        freopen("polygon.out","w",stdout);
        scanf("%I64d",&n);
        for (int i=1;i<=n;i++) scanf("%I64d",&a[i]);
        for (int i=1;i<=n;i++)
                for (int j=1;j<=n;j++) f[i][j][0]=1;
        for (int i=n-2;i>=1;i--)
                for (int j=i+2;j<=n;j++)
                {
                        f[i][j][0]=INF;
                        for (int k=i+1;k<=j-1;k++)
                        {
                                multi(a[i],a[k],a[j],s1);
                                addVal(f[i][k],f[k][j],s2);
                                addVal(s1,s2,s3);
                                if (check(f[i][j],s3)) memcpy(f[i][j],s3,sizeof(f[i][j]));
                        }
                }
        printf("%I64d",f[1][n][f[1][n][0]]);
        for (int i=f[1][n][0]-1;i>=1;i--) printf("I64d",f[1][n][i]);
        printf("\n");
}

----------------------------------------------------------------------------------------------------

T3  系统可靠性问题(TAG:动态规划)

这道题是比较简单的完全背包问题了,但是由于考试时候匆匆忙忙,写萎了,结果只得了10分。含有一个值得注意的地方,读入的时候,对于每一个零件,题目中并没有给出他的备用零件个数选择有多少种方式,所以需要在读入时判断回车符。

代码略。

T4 重复子串问题(TAG:KMP算法)

暴力大法好!有人打了个暴力就A了真是不能忍。。。我开始想过这种做法,但是看到数据范围后就弃疗了,然而并不清楚为什么可以A了。先说说暴力的做法吧:对于每一个字母数字组合,记录其曾经出现过的位置,依次进行比较,得到重复串后判断是否相连即可。正解的话是江哥跟我们讲的,可以巧妙利用KMP算法的fail指针。

代码略。

时间: 2024-11-06 03:25:45

[总结+题解]NOIP2015模拟题2的相关文章

[题解]某模拟题(USACO月赛部分题+noip2005部分题)

题目描述 农场上有N(1 <= N <= 50,000)堆草,放在不同的地点上.FJ有一辆拖拉机,也在农场上.拖拉机和草堆都表示为二维平面上的整数坐标,坐标值在1..1000的范围内.拖拉机的初始位置与所有草堆不同. FJ开拖拉机时,只能平行于坐标轴(即东.南.西.北四个方向),而且每次开动的一段必须是整数长度.例如,他可以向北开2个单位长度,然后向东开3个单位长度.拖拉机不能开到草堆的位置. 请帮助FJ计算出最少要移动多少个草堆,他才能将拖拉机开回坐标原点. 拖拉机可以开到1..1000之外

[题解]某模拟题题解

第一道题还是比较简单,只不过做的时候手贱写错了一个字母,然后活活RE掉了40分 先处理处最终的图,然后从后往前用并查集完成询问.至于之前的删边可以排个序, 然后建一个长度和它一样的boolean数组标志这条边又没被删,删除的时候就lower_bound 就可以了,只不过注意重复的边.如果这一位上为false(这条边被删掉了)应该往后找到 第一个为true的地方,然后将它改为false Code: 1 #include<iostream> 2 #include<cstdio> 3 #

cdoj 25 点球大战(penalty) 模拟题

点球大战(penalty) Time Limit: 20 Sec  Memory Limit: 256 MB 题目连接 http://acm.uestc.edu.cn/#/problem/show/25 Description 在足球比赛中,有不少赛事,例如世界杯淘汰赛和欧洲冠军联赛淘汰赛中,当比赛双方经过正规比赛和加时赛之后仍然不分胜负时,需要进行点球大战来决定谁能够获得最终的胜利.点球大战的规则非常简单,两方轮流派出球员罚点球,每方各罚5个.当5轮点球结束以后如果仍然不分胜负,则进入一轮定胜

JZOJ4316【NOIP2015模拟11.5】Isfind 题解

JZOJ4316 [NOIP2015模拟11.5]Isfind 题解 Description Input Output Sample Input 4 3    acbc    abc    cba    cc Sample Output Y    N    Y Data Constraint 思路: 题意要看懂,首先声明一下"子串"和"子序列"的区别,S的"子串"意思是在S中选取任意i个(0 < i <= |S|)连续字符组成的字符串

10.9 guz模拟题题解

感谢@guz 顾z的题题解 考试共三道题,其中 第一题help共10个测试点,时间限制为 1000ms,空间限制为 256MB. 第二题escape共20个测试点,时间限制为1000ms2000ms,空间限制1MB16MB. 第三题cure共20个测试点,时间限制为 1000ms,空间限制为 256MB. PS:题目背景与题目本身无关,可跳过 help 题目背景 在梦中,王 小 呆 到了一个神秘的地方.这里是昆虫王国!国王见王 小 呆 好生俊俏,便给了他一杯昆虫国的老白干.王 小 呆一口下肚,突

hdu 4119 Isabella&#39;s Message 模拟题

Isabella's Message Time Limit: 20 Sec  Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=4119 Description Isabella and Steve are very good friends, and they often write letters to each other. They exchange funny experiences, talk ab

noip模拟题题解集

最近做模拟题看到一些好的题及题解. 升格思想: 核电站问题 一个核电站有N个放核物质的坑,坑排列在一条直线上.如果连续M个坑中放入核物质,则会发生爆炸,于是,在某些坑中可能不放核物质. 任务:对于给定的N和M,求不发生爆炸的放置核物质的方案总数 输入:输入文件只一行,两个正整数N,M( 1<N<50,2≤M≤5) 输出:输出文件只有一个正整数S,表示方案总数. 运用升格思想.设N个坑不会发生爆炸的方案数是f[N],那么我们假设N以前的坑的方案 都已知了,那么我们只需要考虑第N个坑如何放即可(顺

HDU 4028 The time of a day STL 模拟题

暴力出奇迹.. #include<stdio.h> #include<iostream> #include<algorithm> #include<vector> #include<cmath> #include<queue> #include<set> #include<map> using namespace std; #define ll __int64 #define N 42 ll n,m,ans;

cf428c 模拟题

这题说的是给了 n个数然后又 k次 的交换任意位置的 数字的机会  计算最长的连续子序列的和 这要撸  模拟整个 过程 并不能就是算最长的递增序列 如果只是 找最长的 和序列的 话 会存在 很多问题 在替换的时候 每一个决策 都影响着 下一个决策  这样 存在谁与谁替换 这样的状态有 200!种    那就枚举每个区间这样就可以使得 我们所用替换方法得当  因为在替换中我们进行替换是对不同区间的 操作 比如 在替换序列之内的 数字的时候 其实操作的就是不同的区间 与外面的序列进行替换的时候 操作