题目名称 笔记 括号 城堡
可执行文件名 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. [转] Manacher算法详解

    转载自: http://blog.csdn.net/dyx404514/article/details/42061017 Manacher算法 算法总结第三弹 manacher算法,前面讲了两个字符串 ...

  2. javascript点击图片放大的功能(原生)

    使用的图片: 1.jpg <!doctype html> <html lang="en"> <head> <meta charset=&q ...

  3. Android 所有颜色代码

    colors.xml <?xml version="1.0" encoding="utf-8" ?> <resources> <c ...

  4. Yet Another Scheme Introduction学习

    Chapter 2 Function exact->inexact is to convert from fractional numbers to floating point numbers ...

  5. 查看ssh服务开启状态

    root@dbaudit-desktop:/etc/init.d# /etc/init.d/ssh status * sshd is running 或者这样检查:root@dbaudit-deskt ...

  6. 【Java基础】Java中的持久属性集Properties

    Properties 类的介绍 Properties 类表示了一个持久的属性集.Properties 可保存在流中或从流中加载.属性列表中每个键及其对应值都是一个字符串.一个属性列表可包含另一个属性列 ...

  7. 在VirtualBox中安装了Ubuntu后,Ubuntu的屏幕分辨率非常小,操作非常不便。通过安装VirtualBox提供的“增强功能组件”,-摘自网络

    在VirtualBox中安装了Ubuntu后,Ubuntu的屏幕分辨率非常小,操作非常不便.通过安装VirtualBox提供的“增强功能组件”,可以解决这一问题,并且使用非常方便. 一.环境 | En ...

  8. yuv 图像里的stride和plane的解释

    stride可以翻译为:跨距 stride指在内存中每行像素所占的空间.如下图所示,为了实现内存对齐(或者其它的什么原因),每行像素在内存中所占的空间并不是图像的宽度. plane一般是以luma p ...

  9. openstack 正常流量

  10. glance image cache

    The Glance Image Cache The Glance API server may be configured to have an optional local image cache ...