算法开始阶段(还有些弄不清的,以后多看看,逐步减少)

Sonya and Robots

链接:登录—专业IT笔试面试备考平台_牛客网
来源:牛客网
 

Since Sonya is interested in robotics too, she decided to construct robots that will read and recognize numbers.

Sonya has drawn nnn numbers in a row, aia_iai​ is located in the iii-th position. She also has put a robot at each end of the row (to the left of the first number and to the right of the last number). Sonya will give a number to each robot (they can be either same or different) and run them. When a robot is running, it is moving toward to another robot, reading numbers in the row. When a robot is reading a number that is equal to the number that was given to that robot, it will turn off and stay in the same position.

Sonya does not want robots to break, so she will give such numbers that robots will stop before they meet. That is, the girl wants them to stop at different positions so that the first robot is to the left of the second one.

For example, if the numbers [1,5,4,1,3][1, 5, 4, 1, 3][1,5,4,1,3] are written, and Sonya gives the number 111 to the first robot and the number 444 to the second one, the first robot will stop in the 111-st position while the second one in the 333-rd position. In that case, robots will not meet each other. As a result, robots will not be broken. But if Sonya gives the number 444 to the first robot and the number 555 to the second one, they will meet since the first robot will stop in the 333-rd position while the second one is in the 222-nd position.

Sonya understands that it does not make sense to give a number that is not written in the row because a robot will not find this number and will meet the other robot.

Sonya is now interested in finding the number of different pairs that she can give to robots so that they will not meet. In other words, she wants to know the number of pairs (ppp, qqq), where she will give ppp to the first robot and qqq to the second one. Pairs (pip_ipi​, qiq_iqi​) and (pjp_jpj​, qjq_jqj​) are different if pi≠pjp_i\neq p_jpi​​=pj​ or qi≠qjq_i\neq q_jqi​​=qj​.

Unfortunately, Sonya is busy fixing robots that broke after a failed launch. That is why she is asking you to find the number of pairs that she can give to robots so that they will not meet.

输入描述:

The first line contains a single integer nnn (1≤n≤1051\leq n\leq 10^51≤n≤105) — the number of numbers in a row.

The second line contains nnn integers a1,a2,…,ana_1, a_2, \ldots, a_na1​,a2​,…,an​ (1≤ai≤1051\leq a_i\leq 10^51≤ai​≤105) — the numbers in a row.

输出描述:

Print one number — the number of possible pairs that Sonya can give to robots so that they will not meet.

示例1

输入

复制5 1 5 4 1 3

5
1 5 4 1 3

输出

复制9

9

示例2

输入

复制7 1 2 1 1 1 3 2

7
1 2 1 1 1 3 2

输出

复制7

7

备注:

 
 

In the first example, Sonya can give pairs ($$$1$$$, $$$1$$$), ($$$1$$$, $$$3$$$), ($$$1$$$, $$$4$$$), ($$$1$$$, $$$5$$$), ($$$4$$$, $$$1$$$), ($$$4$$$, $$$3$$$), ($$$5$$$, $$$1$$$), ($$$5$$$, $$$3$$$), and ($$$5$$$, $$$4$$$).

In the second example, Sonya can give pairs ($$$1$$$, $$$1$$$), ($$$1$$$, $$$2$$$), ($$$1$$$, $$$3$$$), ($$$2$$$, $$$1$$$), ($$$2$$$, $$$2$$$), ($$$2$$$, $$$3$$$), and ($$$3$$$, $$$2$$$).

想用我自己的思路再写一次

/*//感觉可以全部列出来然后用集合去重
//再用字典表示有序对,可重复键的字典
//用multimap
#include<bits/stdc++.h>
typedef long long ll;
using namespace std;
int a[100010];
int b[100010]={0};
int main()
{
    multimap<int,int> mp;
    //set<multimap<int,int > > st;
    ll n,tmp1,tmp2;
    cin>>n;
    for(int i=0;i<n;i++)
        {scanf("%d",a+i);
         b[a[i]]++;}
    ll cha;
    cha=0;
    for(int j=0;j<n;j++)
        if(b[j]>1)cha+=b[j]/2;
    for(int i=0;i<n;i++)
        for(int j=i+1;j<n;j++)
            {
                tmp1=a[i];
                tmp2=a[j];
                mp.insert(pair<int, int>(tmp1, tmp2));

                }
    for(multimap<int,int>::iterator it=mp.begin();it!=mp.end();it++)
    {
        printf("%d %d\n",it->first,it->second);}
    ll end;
    end=mp.size();
    printf("用size函数输出的个数%lld   ",end-cha);
    return 0;
}
//这个multimap有点出乎意料,我以为只允许键重复,怎么全都可以重复了。*/
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int a[100010];
int b[100010]={0};
int main()
{
    ll n,i,tmp,maxn;
    i=0;
    maxn=-99;
    cin>>n;
    for(int j=0;j<n;j++)
    {
        scanf("%d",a+i);
        //printf("\n%d",a[i]);
        if(a[i]>maxn)maxn=a[i];
        i++;
    }
    for(int m=0;m<n;m++)
        for(int l=m+1;l<n;l++)
          {tmp=a[m]*10+a[l];
           b[tmp]++;}
           //printf("%lld %d\n",tmp,b[tmp]);}
    ll k,ans;
    ans=0;
    k=maxn*10+maxn;
    for(int j=1;j<=k;j++)
        if(b[j]>=1)ans++;
    printf("%lld",ans);
    return 0;
}


 

#include <bits/stdc++.h>
using namespace std;
int a[100007],b[100007];    
set<int> s;
int main() {
    int n;cin>>n;
    int i;
    for(i=0;i<n;i++) cin>>a[i];
    for(i=0;i<n;i++)
    {
        b[a[i]]=s.size();
        s.insert(a[i]);
    }//相当于是更新寻找到每个元素出现之前,前面有多少个不同的元素可以和它配对
    long long int sum=0;
    for(i=0;i<100001;i++)
    sum+=b[i];
    cout<<sum;
    return 0;
}
//7
//1 2 1 1 1 3 2

Summarize to the Power of Two

​​​​​​​ 

时间限制:C/C++ 3秒,其他语言6秒
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld

题目描述 

A sequence a_1, a_2, \dots, a_na1​,a2​,…,an​ is called good if, for each element a_iai​, there exists an element a_jaj​ (i \ne ji​=j) such that a_i+a_jai​+aj​ is a power of two (that is, 2^d2d for some non-negative integer dd).

For example, the following sequences are good:

  • [5, 3, 11][5,3,11] (for example, for a_1=5a1​=5 we can choose a_2=3a2​=3. Note that their sum is a power of two. Similarly, such an element can be found for a_2a2​ and a_3a3​),
  • [1, 1, 1, 1023][1,1,1,1023],
  • [7, 39, 89, 25, 89][7,39,89,25,89],
  • [][].

Note that, by definition, an empty sequence (with a length of 00) is good.

For example, the following sequences are not good:

  • [16][16] (for a_1=16a1​=16, it is impossible to find another element a_jaj​ such that their sum is a power of two),
  • [4, 16][4,16] (for a_1=4a1​=4, it is impossible to find another element a_jaj​ such that their sum is a power of two),
  • [1, 3, 2, 8, 8, 8][1,3,2,8,8,8] (for a_3=2a3​=2, it is impossible to find another element a_jaj​ such that their sum is a power of two).

You are given a sequence a_1, a_2, \dots, a_na1​,a2​,…,an​. What is the minimum number of elements you need to remove to make it good? You can delete an arbitrary set of elements.

输入描述:

The first line contains the integer nn (1 \le n \le 1200001≤n≤120000) — the length of the given sequence.

The second line contains the sequence of integers a_1, a_2, \dots, a_na1​,a2​,…,an​ (1 \le a_i \le 10^91≤ai​≤109).

输出描述:

Print the minimum number of elements needed to be removed from the given sequence in order to make it good. It is possible that you need to delete all nn elements, make it empty, and thus get a good sequence.

示例1

输入

复制

6
4 7 1 5 4 9

输出

复制

1

示例2

输入

复制

5
1 2 3 4 5

输出

复制

2

示例3

输入

复制

1
16

输出

复制

1

示例4

输入

复制

4
1 1 1 1023

输出

复制

0

备注:

In the first example, it is enough to delete one element $$$a_4=5$$$. The remaining elements form the sequence $$$[4, 7, 1, 4, 9]$$$, which is good.

//这个感觉还挺简单,可以用二进制的位运算进行
#include<bits/stdc++.h>
typedef long long ll;
using namespace std;
ll read()
{
char c=getchar();
ll ds=0,fs=1;
while (c<'0'||'9'<c) {if (c=='-') fs=-1;c=getchar();}
while (c>='0'&&c<='9') ds=(ds<<3)+(ds<<1)+c-48,c=getchar();
return ds*fs;
}
bool judge2(ll sum)
{
    /*ll cnt;
    cnt=2;
    for(int i=0;i<32;i++)
    {
        if(i>=1)
        cnt=cnt<<1;
        if(sum==cnt)return true;//可以为2 的幂
        else continue;
    }
    return false;*/
    for (long long j = 1 << 30; j >= 1; j >>= 1)
        if(j==sum)return true;
        else continue;
    return false;
}
int main()
{
    //set<int> st;
    int n=0;
    n=read();
    int a[n+5];
    bool b[n+5]={false};
    for(int i=0;i<n;i++){
        a[i]=read();}
        //st.insert(a[i]);   }
  //  n1=st.size();
    ll ans;//num1;
    //num1=0;
    if(n==1){
        printf("1");
        return 0;
    }
    ll tmp;
    for(int i=0;i<n;i++)
        for(int j=0;j<n;j++)
        {
            if((i!=j)&&(!b[i]||!b[j])){
            tmp=a[i]+a[j];
            if(judge2(tmp))
            {   //if(!b[i])
                //num1++;
                //if(!b[j])num1++;
                                 //printf("%d %dcan",a[i],a[j]);
                b[i]=true;
                b[j]=true;
                break;}//i号可以找到配对的
                }
        }
    ans=0;
    for(int i=0;i<n;i++)
        if(!b[i])ans++;
    printf("%lld",ans);
    return 0;
}

啊,难过,为什么3000ms都能让我运行超时 。思路和别人一样的,但是用的结构和函数不一样,结果时间超了好多。

//写完这个题就回去睡觉,之后就是明早再赶作业吧。
#include<bits/stdc++.h>
typedef long long ll;
using namespace std;
map<ll,int> mp;//统计相同元素出现次数
map<ll,bool> vis;//记录是否满足要求
//查找数字,使符合条件,两者和为2的幂次.
int main()
{
    ll n,ans;
    ans=0;
    cin>>n;
    int a[n+5];
    for(int i=0;i<n;i++)
    {
        cin>>a[i];
        mp[a[i]]++;
    }
    bool f;//类似函数
    sort(a,a+n);//这个排序后,是会快一些吗
    for(int i=0;i<n;i++)
    {
        if(vis[a[i]])continue;
        f=true;
        for(ll j = 1 << 30;j>=1;j>>=1)//为什么是>>=1
        {
            if(j<a[i])break;
            if(mp.count(j-a[i]))
            {
                if(j-a[i]==a[i]&&mp[a[i]]==1)continue;
                vis[a[i]]=1;
                vis[j-a[i]]=0;//已被配对
                f=false;
                break;
            }
        }
        if(f)ans++;
    }
    printf("%lld",ans);
    return 0;
}

正确代码里有些地方不会。

Guess you like

Origin blog.csdn.net/qq_51976555/article/details/121293094