2.排列 (sum)

时间限制:1s内存限制:256MB 

【问题描述】给出一个随机的排列,请你计算最大值减最小值的差小于等于 0~n-1 的区间分别有多少个。 

【输入】  输入文件名为 sum.in。

 第一行一个数 T(<=10),表示数据组数 

对于每一组数据:第一行一个数 n(1<=n<=100,000) 

第二行 n 个数 a1...an,表示一个随机的排列 

【输出】输出文件名为 sum.out。对于每组数据输出 n 行,分别表示差值小于等于 0~n-1 的区间个数 

【输入输出样例】sum.in sum.out 

1                                4

4   5

3 2 4 1   7

  10

 【数据说明】对于 30%的数据,1<=n<=300;对于 60%的数据,1<=n<=5000 ;对于 100%的数据,1<=n<=100000.

比起上个星期的题目,这一次还算有点noip的水平(liang xin)(毕竟我终于会做一点了~虽然还不知道对不对。。。)

作为一名pascal选手,代码就是要简单粗暴(当我没说— …—|||)

文件的读入输出:

procedure fin;
begin
assign(input,'sum.in');
assign(output,'sum.out');
reset(input); rewrite(output);
end;
procedure fout;
begin
close(input);
close(output);
end;

变量定义:

var
   maxn,minn,f,k,ans,j,i,t,n:longint;
   s_cha,a:array[0..100010]of longint;


方案一:暴力  将文件的输入存入数组中,写两个在区间内寻找最值的函数,然后从1到n,每一次都去寻找max与min,找到之后进行比较,看是否与0~n-1的值相等,若相等则+1.

function max(l,r:longint):longint;//区间内找最大
var ff,i:longint;
begin
  ff:=0;
  for i:=l to r do if ff<a[i] then ff:=a[i];
  exit(ff);
end;
function min(l,r:longint):longint;//区间内找最小
var ff,i:longint;
begin
  ff:=maxlongint;
   for i:=l to r do if ff>a[i] then ff:=a[i];
   exit(ff);
end;
begin
//fin;
  readln(t);
for f:=1 to t do begin
  readln(n);
    for i:=1 to n do begin
     read(a[i]);
    end;
    ans:=0;
    for i:=1 to n-1 do
     if a[i]=a[i+1] then inc(ans);
    s_cha[0]:=ans+n;

    for i:=1 to n-1 do
    begin
     ans:=0;
       for j:=1 to n do
         for k:=j+1 to n do
           if max(j,k)=i+min(j,k) then inc(ans);
     s_cha[i]:=s_cha[i-1]+ans;
    end;
  for i:=1 to n do
   writeln(s_cha[i-1]);
filchar(s_cha,sizeof(s_cha),0); //数组清0继续程序。
end;
//fout;
end.


由上述的暴力我们知道T(n)>=O(t*(n^3)),再看一下数据:1<=n<=100000,1<=t<=10,O(n^2)的要求啊~so。。。。大笑

方法二:  比较巧妙的暴力~

直接暴力一边数组,把相应的差值数组自加。

begin
//fin;
  readln(t);
for f:=1 to t do begin
  readln(n);
    for i:=1 to n do begin
     read(a[i]);
    end;
    a[0]:=n;

    for j:=1 to n do
    begin
     maxn:=a[j]; minn:=a[j];
     for k:=j to n do begin
       if a[k]<minn then minn:=a[k];
       if a[k]>maxn then maxn:=a[k];
       inc(s_cha[maxn-minn]); end;
    end;
    for i:=1 to n do
     inc(s_cha[i],s_cha[i-1]);
  for i:=1 to n do
   writeln(s_cha[i-1]);
filchar(s_cha,sizeof(s_cha),0); 
end;
//fout;
end.

不知道能不能过。。。

如果有点小问题请自行修改哦。

cpp代码:(文件的读入输出我就不写啦~\(≧▽≦)/~啦啦啦)

#include<bits/stdc++.h>
#define inf 100010
using namespace std;
int main()
{
    int t,n,i,j,ans,k,minn,maxn;
    int a[inf],s_cha[inf];
    scanf("%d",&t);
    for(int f=1;f<=t;f++){
        scanf("%d",&n);
         for (i=1;i<=n;i++) scanf("%d",&a[i]);
        for (j=1;j<=n;++j){
            maxn=a[j]; minn=a[j];
            for (k=j;k<=n;k++){
                if(a[k]<minn) minn=a[k];
                if(a[k]>maxn) maxn=a[k];
                s_cha[maxn-minn]++;
            }
        }
        for (i=1;i<=n;++i) s_cha[i]+=s_cha[i-1];
        for (i=1;i<=n;++i) printf("%d\n",s_cha[i-1]);
        memset(s_cha,0,sizeof(s_cha));
    }
    return 0;
}

终于会用csdn了,好开森啊 微笑 (跪求大佬的评论)


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
这段代码使用了熵权法和Topsis方法对数据进行多指标决策分析。以下是对代码的分析: 1. 读取数据:使用`readmatrix`函数从名为'data_112.xlsx'的Excel文件中读取数据,并将数据存储在变量`a`中。 2. 数据预处理:将第一列删除,保留剩余的数据。使用`size`函数获取数据矩阵的行数和列数,并分别存储在变量`n`和`m`中。 3. 计算概率矩阵:将数据矩阵`a`中的每个元素除以其所在列的总和,得到概率矩阵。将概率矩阵存储在变量`p`中。 4. 计算信息熵:使用信息熵公式计算概率矩阵的信息熵,将结果存储在变量`e`中。 5. 计算变异系数:将信息熵去1得到变异系数,将结果存储在变量`g`中。 6. 计算权重:将变异系数除以所有变异系数的总和,得到每个指标的权重。将权重存储在变量`w`中。 7. 读取数据:使用`readmatrix`函数再次读取数据,并将数据存储在变量`b`中。 8. 数据预处理:将第一列删除,保留剩余的数据。 9. 归一化处理:将数据矩阵`b`中的每个元素除以其所在列的2范数,得到归一化矩阵。将归一化矩阵存储在变量`c`中。 10. 加权处理:将归一化矩阵`c`的每个元素与对应的权重相乘,得到加权矩阵。将加权矩阵存储在变量`f`中。 11. 极大值和极小值处理:分别计算加权矩阵`f`每列的最大值最小值,并将结果存储在变量`Cstmax`和`Csmin`中。 12. 计算正理想解与负理想解的欧式距离:计算加权矩阵`f`与极大值和极小值之间的欧式距离,分别存储在变量`Ds1`和`Ds0`中。 13. 计算综合得分:根据欧式距离计算综合得分,将结果存储在变量`zhfs`中。 14. 排序和指标排序:对综合得分进行降序排序,同时获取排序后的索引,分别存储在变量`sf`和`lind`中。`sf`表示按综合得分降序排列后的结果,`lind`表示排序后的索引。 通过这段代码,可以得到按照多指标综合得分进行排序的结果。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值