zoukankan      html  css  js  c++  java
  • 2019年1月26日训练日记

    今天写两个代码的简化问题,注意问题:数组越界,超时间,超内存,for循环内有时需要每次清零,以及==时不要再写成=,因为真的不易检查。
    2114 多出的数字
    给你m个1到n之间的整数,你能找出1到n中的哪些整数出现了多次吗?
    输入
    第一行2个整数n,m,直接用空格分隔(n <= 100000, n < m < 2n),表示有m个1到n之间的整数。
    接下来m行,每行一个整数ai(1 <= ai <=n)。
    输出
    若干行,每行两个数ai和bi,从小到大输出输入数据中出现了超过1次的1到n中的整数ai和它出现的次数bi。
    输入样例

    5 7
    1
    1
    5
    2
    4
    4
    3
    

    输出样例

    1 2
    4 2
    

    代码一:

    #include <cmath>
    #include <cstdio>
    #include <vector>
    #include <iostream>
    #include <algorithm>
    #include<cstring>
    using namespace std;
    int a[100001],b[100001];
    int main()
    {
        int n,m,x;
        cin>>n>>m;
        memset(b,0,sizeof(b));
        for(int i=1;i<=m;i++)
        {
            cin>>x;
            for(int j=1;j<=n;j++)
                a[j]=j;
                for(int j=1;j<=n;j++)
                if(x==a[j])
                b[j]++;
        }
        for(int i=1;i<=n;i++)
        {
            if(b[i]>1)
            cout<<a[i]<<" "<<b[i]<<endl;
        }
    	return 0;
    }
    

    以上数组用了两个,循环次数较多,容易超时。。。

    代码二:

    #include <bits/stdc++.h>
    using namespace std;
    int n,m,a[200005]={},b[100005]={};
    int main()
    {
        cin>>n>>m;
        for(int i=1;i<=m;i++)
        {
            cin>>a[m];
            b[a[m]]++;
        }
        for(int i=1;i<=n;i++)
        {
            if(b[i]>1)
            cout<<i<<" "<<b[i]<<endl;
        }
        return 0;
    
    }
    

    这个是正确的代码。除去第一个代码超时不算的话,还可能导致超内存,即数组越界问题:
    输入
    第一行2个整数n,m,直接用空格分隔(n <= 100000, n < m < 2n),在这里可以看出m的大小,当一个在1-n内的数据出现上述范围以上时会越界。
    当然第二个也可能出现越界问题,因此一定要读清楚题目,防止越界。

    2128 前缀异或
    输入一个长度为n(1 <= n <= 100000)数组a[1], a[2], …, a[n]。
    输入一个询问数m(1 <= m <= 100000)和m组询问,每组询问形如(l, r)
    对于每组询问(l, r),你需要输出a[l] xor a[l + 1] xor … xor a[r - 1] xor a[r],即第l个数字到第r个数字的异或。
    如果你的算法需要约n*m的时间,你将只能通过第一个测试点。
    如果你的算法需要约n+m的时间,你将可以通过本题。
    输入
    第一行一个整数n
    第二行为n个整数a[1], a[2], … a[n]
    第三行一个整数m
    接下来m行,每行两个整数l, r表示询问。
    输出
    输出一共m行,对于每一个询问输出一个整数表示结果。
    输入样例

    3
    1 2 3
    6
    1 1
    2 2
    3 3
    1 2
    2 3
    1 3
    

    输出样例

    1
    2
    3
    3
    1
    0
    

    代码一:

    #include <cmath>
    #include <cstdio>
    #include <vector>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    int a[100001];
    int main()
    {
        int n,m,x,y,s=0;
        cin>>n;
        for(int i=1;i<=n;i++)
        {
           cin>>a[i];
        }
        cin>>m;
        for(int i=1;i<=m;i++)
        {
            cin>>x>>y;
            for(int j=x;j<=y;j++)
            s=s^a[j];
                cout<<s<<endl;
                s=0;
        }
        return 0;
    }
    

    算法需要约nm的时间:
    每次循环(y-x)次(按n次算),共m次,即m
    n次。
    这样会超时。。。

    代码二:

    #include <cstdio>
    using namespace std;
    int a[200002];
    int main()
    {
        int n,m;
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
        {
            int x;
            scanf("%d",&x);
            a[i]=a[i-1]^x;
        }
        scanf("%d",&m);
        while(m--)
        {
            int l,r;
            scanf("%d%d",&l,&r);
            printf("%d
    ",a[r]^a[l-1]);
        }
    }
    

    这样来算提前n次就把之前的数依次异或过,当输出y-x(l,r)间异或时只需a[r]^a[l-1]一步即可,总计m+n步。

  • 相关阅读:
    Ubuntu16.04.1 安装Nginx
    Ubuntu16.04.1 安装Redis-Cluster
    SeekBar的简单使用
    Async异步处理
    SQLite
    Shareprefrence
    android中的主线程
    Fragment的简单使用
    ArrayAdapter的使用
    用Intent传递对数
  • 原文地址:https://www.cnblogs.com/study-hard-forever/p/12130076.html
Copyright © 2011-2022 走看看