题目名称 笔记 括号 城堡
可执行文件名 note brackets castle
输入文件名 note.in brackets.in castle.in
输出文件名 note.in brackets.out castle.in
每个测试点时限 1 秒 1 秒 1 秒
内存限制 512MB 512MB 512MB
测试点数目 20 20 10
每个测试点分值 5 5 10
是否有部分分 否 否 否
题目类型 传统型 传统型 传统型
测试题 #4 笔记
笔记
【问题描述】
给定一个长度为?的序列?,下标编号为1~?。序列的每个元素都是1~?的
整数。定义序列的代价为
? ?+1 − ? ?
?−1
?=1
你现在可以选择两个数?和?,并将序列?中所有的?改成?。?可以与?相等。
请求出序列最小可能的代价。
【输入格式】
输入第一行包含两个整数?和?。第二行包含?个空格分隔的整数,代表序
列?。
【输出格式】
输出一行,包含一个整数,代表序列最小的代价。
【样例输入 1】
4 6
1 2 3 4 3 2
【样例输出 1】
3
【样例输入 2】
10 5
9 4 3 8 8
【样例输出 1】
6
【样例解释】
样例 1 中,最优策略为将 4 改成 3。样例 2 中,最优策略为将 9 改成 4。
测试题 #4 笔记
【数据规模和约定】
31。
60%的数据,?,? ≤ 2000。
对于100%的数据,1 ≤ ?,? ≤ 100,000。

/*暴力+小小的优化(没有啥大用)*/
#include<cstdio>
#include<ctime>
#include<algorithm>
#define maxn 100010
using namespace std;
int n,m,a[maxn],b[maxn],c[maxn],ans;
int init(){
int x=,f=;char s=getchar();
while(s<''||s>''){if(s=='-')f=-;s=getchar();}
while(s>=''&&s<=''){x=x*+s-'';s=getchar();}
return x*f;
}
int Abs(int x){
return x<?-x:x;
}
int main()
{
freopen("note.in","r",stdin);
freopen("note.out","w",stdout);
n=init();m=init();
for(int i=;i<=m;i++)
a[i]=init();
if(n<=){
for(int i=;i<m;i++)
if((a[i]<a[i-]&&a[i]<a[i+])||(a[i]>a[i-]&&a[i]>a[i+]))
c[++c[]]=a[i];
c[++c[]]=a[];c[++c[]]=a[m];
}
else for(int i=;i<=n;i++)c[++c[]]=a[i];
sort(c+,c++c[]);
c[]=unique(c+,c++c[])-c-;
for(int i=;i<m;i++)
ans=ans+Abs(a[i+]-a[i]);
for(int i=;i<=c[];i++)
for(int j=;j<=n;j++){
for(int k=;k<=m;k++)
if(a[k]==c[i])b[k]=j;
else b[k]=a[k];
long long mx=;
for(int k=;k<m;k++){
mx=mx+Abs(b[k+]-b[k]);
if(ans<mx)break;
}
if(ans>mx)ans=mx;
//if(clock()>950){
// printf("%lld\n",ans);return 0;
//}
}
printf("%lld\n",ans);
fclose(stdin);fclose(stdout);
return ;
}
/*
嗯很好的思路 每个数字只与两边的有关
假设我们尝试着改 x 改成什么玩意是可以直接算出来的
先预处理处所有与x相邻的数们 那每个都要与x做差然后绝对值
如果我们队这一坨数排序的话 那么显然x改成中位数最优
然后枚举一下x 比较一下就好了
每个x都要sort一遍 这个并不会很慢 均摊还是很快的
*/
#include<cstdio>
#include<vector>
#include<algorithm>
#define maxn 100010
#define ll long long
using namespace std;
ll n,m,a[maxn],b[maxn];
ll sta,mx;
vector<ll>G[maxn];
ll init(){
ll x=,f=;char s=getchar();
while(s<''||s>''){if(s=='-')f=-;s=getchar();}
while(s>=''&&s<=''){x=x*+s-'';s=getchar();}
return x*f;
}
ll Abs(ll x){
return x<?-x:x;
}
int main(){
freopen("note.in","r",stdin);
freopen("note.out","w",stdout);
n=init();m=init();
for(ll i=;i<=m;i++)a[i]=init();
for(ll i=;i<=m;i++)
if(a[i]!=a[i-])b[++b[]]=a[i];
for(ll i=;i<m;i++)sta+=Abs(a[i+]-a[i]);
m=b[];b[]=;
for(ll i=;i<m;i++){
G[b[i]].push_back(b[i-]);
G[b[i]].push_back(b[i+]);
}
if(b[])G[b[]].push_back(b[]);
if(b[m-])G[b[m]].push_back(b[m-]);
for(ll i=;i<=n;i++){
ll len=G[i].size();
if(!len)continue;
sort(G[i].begin(),G[i].end());
ll mid=G[i][(len+)/-];
ll pre=,now=;
for(ll k=;k<len;k++){
pre+=Abs(G[i][k]-i);
now+=Abs(G[i][k]-mid);
}
mx=max(mx,pre-now);
}
printf("%I64d\n",sta-mx);
return ;
}

测试题 #4 括号
括号
【问题描述】
有一个长度为?的括号序列,以及?种不同的括号。序列的每个位置上是哪
种括号是随机的,并且已知每个位置上出现每种左右括号的概率。求整个序列是
一个合法的括号序列的概率。
我们如下定义合法括号序列:
 空序列是合法括号序列;
 如果?是合法括号序列,那么???是合法括号序列,当且仅当?和?是同种
的左右括号;
 如果?和?是合法括号序列,那么??是合法括号序列。
【输入格式】
输入第一行包含两个整数?和?。接下来的输入分为?组,每组?行。第?组第
?行包含两个实数?[?,?]和?[?,?],分别代表第?个位置上是第?类的左括号和右括号
的概率。
【输出格式】
输出一行,包含一个实数,代表序列是合法括号序列的概率。建议保留至少
5 位小数输出。只有当你的输出与标准答案之间的绝对误差不超过10 −5 时,才会
被判为正确。
【样例输入 1】
2 1
1.00000 0.00000
0.00000 1.00000
【样例输出 1】
1.00000
【样例输入 2】
4 1
0.50000 0.50000
1.00000 0.00000
0.00000 1.00000
0.50000 0.50000
测试题 #4 括号
【样例输出 2】
0.25000
【数据规模和约定】
对于20%的数据,? ≤ 50,? = 1,所有位置的概率非 0 即 1。
另外有 30%的数据,? ≤ 34,? = 1,前 10 个和后 10 个位置的所有概率都
是 0.5,中间剩余位置的概率非 0 即 1。
80%的数据,?,? ≤ 50。
对于100%的数据,1 ≤ ? ≤ 200,1 ≤ ? ≤ 50。

/*dpwa成了傻逼 还是交的暴力*/
#include<iostream>
#include<cstdio>
#define maxn 210
#define ld long double
using namespace std;
int n,k,s[maxn];
ld g[maxn][maxn][],ans;
void Dfs(int now,ld x){
if(now==n+){
int falg=;
for(int i=;i<=k;i++)
if(s[i]){
falg=;break;
}
if(falg)ans+=x;return;
}
for(int i=;i<=k;i++){
if(s[i]->=&&g[now][i][]){
s[i]--;Dfs(now+,x*g[now][i][]);s[i]++;
}
if(s[i]+<=n-now&&g[now][i][]){
s[i]++;Dfs(now+,x*g[now][i][]);s[i]--;
} }
}
int main()
{
freopen("brackets.in","r",stdin);
freopen("brackets.out","w",stdout);
cin>>n>>k;
for(int i=;i<=n;i++)
for(int j=;j<=k;j++)
cin>>g[i][j][]>>g[i][j][];
if(n&){
printf("0.00000\n");return ;
}
Dfs(,);printf("%.5lf",double(ans));
fclose(stdin);fclose(stdout);
return ;
}
/*维护两个数组 很好的解决了重复计算的问题*/
#include<iostream>
#include<cstdio>
#define ld long double
#define maxn 210
using namespace std;
int n,k;
ld f[maxn][maxn],ff[maxn][maxn],g[maxn][maxn][];
int main(){
freopen("brackets.in", "r", stdin);
freopen("brackets.out", "w", stdout);
cin>>n>>k;
for(int i=;i<=n;i++)
for(int j=;j<=k;j++)
cin>>g[i][j][]>>g[i][j][];
for(int i=;i<n;i++)
for(int x=;x<=k;x++)
f[i][i+]+=g[i][x][]*g[i+][x][];
for(int i=n-;i>=;i--)
for(int j=i+;j<=n;j++){
for(int x=;x<=k;x++)
f[i][j]+=(f[i+][j-]+ff[i+][j-])*g[i][x][]*g[j][x][];
for(int x=i+;x<j-;x++)
ff[i][j]+=(f[i][x]+ff[i][x])*f[x+][j];
}
printf("%.5f\n",(double)(f[][n]+ff[][n]));
return ;
}

测试题 #4 城堡
城堡
【问题描述】
给定一张?个点?条边的无向连通图,每条边有边权。我们需要从?条边中
选出? − 1条, 构成一棵树。 记原图中从 1 号点到每个节点的最短路径长度为? ? ,
树中从 1 号点到每个节点的最短路径长度为? ? ,构出的树应当满足对于任意节点
?,都有? ? = ? ? 。
请你求出选出? − 1条边的方案数。
【输入格式】
输入的第一行包含两个整数?和?。
接下来?行,每行包含三个整数?、?和?,描述一条连接节点?和?且边权为
?的边。
【输出格式】
输出一行,包含一个整数,代表方案数对2 31 − 1取模得到的结果。
【样例输入】
3 3
1 2 2
1 3 1
2 3 1
【样例输出】
2
【数据规模和约定】
32 ≤ ? ≤ 5,? ≤ 10。
对于50%的数据,满足条件的方案数不超过 10000。
对于100%的数据,2≤ ? ≤ 1000,? − 1 ≤ ? ≤
? ?−1
2
,1 ≤ ? ≤ 100。

/*暴力 dfs+SPFA+Tarjan+dfs*/
#include<cstdio>
#include<queue>
#include<iostream>
#include<cstring>
#define maxn 1010
using namespace std;
int n,m,num,head[maxn],f[maxn],D[maxn],S[maxn],topt,top;
int s[maxn],vis[maxn],dfn[maxn],low[maxn],sum,Sum[maxn];
long long ans;
struct node{
int u,v,t;
}p[maxn];
struct edge{
int v,t,pre,x;
}e[maxn*];
queue<int>q;
int init(){
int x=,f=;char s=getchar();
while(s<''||s>''){if(s=='-')f=-;s=getchar();}
while(s>=''&&s<=''){x=x*+s-'';s=getchar();}
return x*f;
}
void Add(int from,int to,int dis,int i){
num++;e[num].v=to;
e[num].x=i;
e[num].t=dis;
e[num].pre=head[from];
head[from]=num;
}
void Tarjan(int x,int fa){
dfn[x]=low[x]=++topt;
s[++top]=x;vis[x]=;
for(int i=head[x];i;i=e[i].pre){
int v=e[i].v;
if(v==fa||!f[e[i].x])continue;
if(dfn[v]==){
Tarjan(v,x);low[x]=min(low[x],low[v]);
}
else if(vis[v])low[x]=min(low[x],dfn[v]);
}
if(low[x]==dfn[x]){
sum++;while(x!=s[top]){
Sum[sum]++;vis[s[top]]=;top--;
}
Sum[sum]++;vis[s[top]]=;top--;
}
}
bool Judge(){
memset(dfn,,sizeof(dfn));
memset(low,,sizeof(low));
memset(s,,sizeof(s));
memset(vis,,sizeof(vis));
memset(Sum,,sizeof(Sum));
topt=top=sum=;
for(int i=;i<=n;i++)
if(dfn[i]==)Tarjan(i,);
for(int i=;i<=sum;i++)
if(Sum[i]>)return ;
return ;
}
void SPFA(){
memset(D,/,sizeof(D));
D[]=;f[]=;q.push();
while(!q.empty()){
int k=q.front();q.pop();f[k]=;
for(int i=head[k];i;i=e[i].pre){
int v=e[i].v;
if(D[v]>D[k]+e[i].t){
D[v]=D[k]+e[i].t;
if(f[v]==){
f[v]=;q.push(v);
}
}
}
}
}
void dfs(int now,int from,int x){
S[now]=min(S[now],x);
for(int i=head[now];i;i=e[i].pre){
if(!f[e[i].x])continue;
int v=e[i].v;if(v==from)continue;
dfs(v,now,x+e[i].t);
}
}
void Solve(){
memset(S,/,sizeof(S));
S[]=;dfs(,,);
for(int i=;i<=n;i++)
if(S[i]!=D[i])return;
ans++;return;
}
void Dfs(int now){
if(now==m+){
int cnt=;
for(int i=;i<=m;i++)
if(f[i])cnt++;
if(cnt!=n-||!Judge())return;
Solve();return;
}
f[now]=;Dfs(now+);
f[now]=;Dfs(now+);
}
int main()
{
freopen("castle.in","r",stdin);
freopen("castle.out","w",stdout);
n=init();m=init();
int u,v,t;
for(int i=;i<=m;i++){
u=init();v=init();t=init();
p[i].u=u;p[i].v=v;p[i].t=t;
Add(u,v,t,i);Add(v,u,t,i);
}
SPFA();memset(f,,sizeof(f));Dfs();
cout<<ans<<endl;
fclose(stdin);fclose(stdout);
return ;
}
/*
很机智的题解
维护每个点连出去的边中 有几个是最短路上的
假设 两个点 ij i有a条连边是最短路上的 j有b条
那么 1 i j 这三个点构成一棵树就有 1*a*b中方法
加上其他的点同理
最后乘法原理算一下
*/
#include<cstdio>
#include<queue>
#include<iostream>
#include<cstring>
#define ll long long
#define mod ((1<<31)-1)
#define maxn 1010
using namespace std;
int n,m,num,head[maxn],f[maxn],D[maxn],c[maxn];
ll ans=;
struct node{
int u,v,t;
}p[maxn*maxn];
struct edge{
int v,t,pre;
}e[maxn**maxn];
queue<int>q;
int init(){
int x=,f=;char s=getchar();
while(s<''||s>''){if(s=='-')f=-;s=getchar();}
while(s>=''&&s<=''){x=x*+s-'';s=getchar();}
return x*f;
}
void Add(int from,int to,int dis){
num++;e[num].v=to;
e[num].t=dis;
e[num].pre=head[from];
head[from]=num;
}
void SPFA(){
memset(D,/,sizeof(D));
D[]=;f[]=;q.push();
while(!q.empty()){
int k=q.front();q.pop();f[k]=;
for(int i=head[k];i;i=e[i].pre){
int v=e[i].v;
if(D[v]>D[k]+e[i].t){
D[v]=D[k]+e[i].t;
if(f[v]==){
f[v]=;q.push(v);
}
}
}
}
}
int main()
{
freopen("castle.in","r",stdin);
freopen("castle.out","w",stdout);
n=init();m=init();
int u,v,t;
for(int i=;i<=m;i++){
u=init();v=init();t=init();
p[i].u=u;p[i].v=v;p[i].t=t;
Add(u,v,t);Add(v,u,t);
}
SPFA();
for(int i=;i<=m;i++){
if(D[p[i].v]==D[p[i].u]+p[i].t)c[p[i].v]++;
if(D[p[i].u]==D[p[i].v]+p[i].t)c[p[i].u]++;
}
for(int i=;i<=n;i++)
ans=ans*(ll)c[i]%mod;
cout<<ans<<endl;
fclose(stdin);fclose(stdout);
return ;
}

11.13 noip模拟试题的更多相关文章

  1. 11.14 noip模拟试题

      题目名称 正确答案 序列问题 长途旅行 英文名称 answer sequence travel 输入文件名 answer.in sequence.in travel.in 输出文件名 answer ...

  2. 11.12 noip模拟试题

    题目名称 加密 冒泡排序图 重建可执行文件名 encrypt bubble rebuild输入文件名 encrypt.in bubble.in rebuild.in输出文件名 encrypt.in b ...

  3. 11.9 noip模拟试题

    NOIP2016 模拟赛——那些年,我们学过的文化课背单词(word.c/cpp/pas)[题目描述]fqk 退役后开始补习文化课啦, 于是他打开了英语必修一开始背单词. 看着满篇的单词非常头疼, 而 ...

  4. 11.10 noip模拟试题

    1.第K小数 (number.cpp/c/pas) [问题描述] 有两个正整数数列,元素个数分别为N和M.从两个数列中分别任取一个数 相乘,这样一共可以得到N*M个数,询问这N*M个数中第K小数是多少 ...

  5. 10.13 noip模拟试题

    Porble 1时间与空间之旅(tstrip.*) 题目描述 公元22××年,宇宙中最普遍的交通工具是spaceship.spaceship的出现使得星系之间的联系变得更为紧密,所以spaceship ...

  6. 11.7 NOIP模拟赛

    目录 2018.11.7 NOIP模拟 A 序列sequence(two pointers) B 锁lock(思路) C 正方形square(埃氏筛) 考试代码 B C 2018.11.7 NOIP模 ...

  7. 11/1 NOIP 模拟赛

    11.1 NOIP 模拟赛 期望得分:50:实际得分:50: 思路:暴力枚举 + 快速幂 #include <algorithm> #include <cstring> #in ...

  8. 10.11 noip模拟试题

    4题均为128M,1s 1. 锻炼计划(exercise.pas) 身体是革命的本钱,OIers不要因为紧张的学习和整天在电脑前而忽视了健康问题.小x设计了自己的锻炼计划,但他不知道这个计划是否可行, ...

  9. 10.4 noip模拟试题

    题目名称 PA 青春 三部曲 名称 huakai taritari truetears 输入 huakai.in taritari.in truetears.in 输出 huakai.out tari ...

随机推荐

  1. 百万程序员的苦恼-选择VB.NET还是C#

    在过去的一年中,互联网上的各大讨论区或者电子邮件的讨论列表都对微软的VB.NET以及C#的各种优越性做了探讨.这些讨论围绕的主要问题就是,我应该先学哪一个,VB.NET还是C#?? 我写这篇文章的目的 ...

  2. find和findstr

    find与findstr 例“ 在文件中搜索字符串. 1.findstr . 2.txt 或 Findstr "." 2.txt 从文件2.txt中查找任意字符,不包括空字符或空行 ...

  3. Win32下 Qt与Lua交互使用(四):在Lua脚本中自由执行Qt类中的函数

    话接上篇.通过前几篇博客,我们实现在Lua脚本中执行Qt类中函数的方法,以及在Lua脚本中连接Qt对象的信号与槽. 但是,我们也能发现,如果希望在Lua脚本中执行Qt类的函数,就必须绑定一个真正实现功 ...

  4. sqliteExpert软件使用(创建数据库和表)

    sqliteExpert是sqlite数据库的可视化操作软件,通过该软件可以进行可视化的创建数据库以及表,免去了复杂的建表语句.首先在下面地址下载该软件http://www.ddooo.com/sof ...

  5. 分割函数和根据Id串返回名字

    需求:函数传入一个字符串参数 例如  123-456 将这个字符串123-456拆成两个值 123   456,在通过两个值分别查出数据(例如 张三  李四),拼接成     张三-李四 --声明变量 ...

  6. Asp.net MVC中的ViewData与ViewBag

    Asp.net MVC中的ViewData与ViewBag 在Asp.net MVC 3 web应用程序中,我们会用到ViewData与ViewBag,对比一下: ViewData ViewBag 它 ...

  7. 杨氏矩阵 leecode 提

    提交网址https://oj.leetcode.com/problems/search-a-2d-matrix/ 有个矩阵中的数,从左向右递增,从上而下递增,快速查找是一个数是是否存在,剑指offer ...

  8. AABB碰撞盒

    矩形边界框(转) 另一种常见的用来界定物体的几何图元是矩形边界框,矩形边界框可以是与轴对齐的或是任意方向的.轴对齐矩形边界框有一个限制,就是它的边必须垂直于坐标轴.缩写AABB常用来表示axially ...

  9. ionic如何uglify和minify你的js,css,image,png....

    Install:   1.ionic start myapp blank      2.cd myapp     3.npm install cordova-uglify or npm install ...

  10. [读书笔记]了不起的node.js+实践(一)

    环境的变化带来了技术大跃进,机遇和挑战同时到来.基于我js也没有学,只好赶鸭子上架一起学了.(>﹏<) 1.先读读书 一开始就不知死活地看<深入浅出node.js>,弄得团团转 ...