题目名称 笔记 括号 城堡
可执行文件名 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. POJ 2253 Frogger(最小生成树)

    青蛙跳跃,题意大概是:青蛙从起点到终点进行一次或多次的跳跃,多次跳跃中肯定有最大的跳跃距离.求在所有的跳跃中,最小的最大跳跃距离SF-_-(不理解?看题目吧). 可以用最小生成树完成.以起点为根,生成 ...

  2. JDK/bin目录下的不同exe文件的用途(转)

    新安装完JDk 大家是否发现安装目录的bin文件夹有很多exe文件 下面就为大家讲解不同exe文件的用途 javac:Java编译器,将Java源代码换成字节代 java:Java解释器,直接从类文件 ...

  3. UVA 1351 - String Compression

    题意: 对于一个字符串中的重复部分可以进行缩写,例如"gogogo"可以写成"3(go)",从6个字符变成5个字符.."nowletsgogogole ...

  4. Ruby应用记录:修改文件中某个字符串

    #修改android客户端中服务器地址的默认值为对应环境的服务器地址 #!/usr/bin/ruby ostr="192.168.88.95:8088" nstr="19 ...

  5. linux 开机自动挂载ntfs盘

    1) 查看盘符UUID vellbibi@vell001:~$ sudo blkid [sudo] password for vellbibi: /dev/sda1: UUID="bce9e ...

  6. HW3.6

    import java.util.Scanner; public class Solution { public static void main(String[] args) { Scanner i ...

  7. [Locked] Unique Word Abbreviation

    Unique Word Abbreviation An abbreviation of a word follows the form <first letter><number&g ...

  8. POJ2104&&HDU2665(静态区间第K小)

    题目大意 给定一个有N个数字的序列,然后又m个查询,形式如下: l r k 要求你返回区间[l,r]第k小的数是哪个 题解 终于弄懂主席树是个啥东西了,O(∩_∩)O~~,这题正是主席树的裸题,主席树 ...

  9. sql中用逗号拼接字符串

    MSSQL中可以用STUFF函数拼接成字符串. 如: SELECT FieldSomeElse, ( SELECT STUFF(( SELECT ',' + LinkField FROM Detail ...

  10. JDBC与SQL SERVER各个版本的连接方法

    转至:blog.csdn.net/ying5420/article/details/4488246 1.SQL SERVER 2000 JDBC驱动程序:msbase.jar.mssqlserver. ...