首页 > 试题广场 >

小球投盒

[编程题]小球投盒
  • 热度指数:2702 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 256M,其他语言512M
  • 算法知识视频讲解
小红一共有 n 个盒子,标号为 1 到 n,小红向盒子里放入小球 m 次,每次进行以下两个操作中的一个:
1. 向编号为 x 的盒子里放入一个小球;
2. 向除了编号为 x 的其他 n - 1 盒子里放入一个小球。
小红想知道,第几次操作之后,所有盒子里至少都有一个小球,如果一直无法达到这个目标,输出 -1

输入描述:
第一行两个整数 nm,表示盒子的数量和操作的次数。
接下来 m 行,每行两个整数 t_ix_i,表示第 i 次操作的类型和 x 的值。
1 \leq n, m \leq 10^5
1 \leq t_i \leq 2
1 \leq x_i \leq n


输出描述:
输出一个整数,表示第几次操作之后,所有盒子里至少都有一个小球,如果一直无法达到这个目标,输出 -1
示例1

输入

3 3
1 1
1 2
1 3

输出

3

说明

三次操作之后,所有盒子里都至少有一个小球。
示例2

输入

3 4
1 1
2 2
1 3
1 2

输出

4

说明

第一次操作后,盒子 1 里有小球。
第二次操作后,盒子 1、3 里有小球。
第三次操作后,盒子 1、3 里有小球。
第四次操作后,每个盒子里都有小球。

import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt(), m = sc.nextInt();
        Set<Integer> set = new HashSet<>();
        for (int i = 1; i <= n; i++) set.add(i);
        int i;
        for (i = 1; i <= m; i++) {
            if (sc.nextInt() == 1) {
                set.remove(sc.nextInt());
                if (set.isEmpty()) break;
            }
            else {
                int x = sc.nextInt();
                if (!set.contains(x)) break;
                set = new HashSet<>();
                set.add(x);
            }
        }
        System.out.println(i > m ? -1 : i);
    }
}

编辑于 2023-08-31 17:21:27 回复(3)
考察流程控制的? 我还以为是什么算法

#include <bits/stdc++.h>
#include <set>
using namespace std;
 
int m, n, t, x;
const int N = 1e5 + 10;
unordered_set<int> op1, op2;
 
int main() {
    cin >> n >> m;
 
    for (int i = 1; i <= m; i++) {
        cin >> t >> x;
        if (t == 1) {
            op1.insert(x);
            if (op1.size() == n) {
                cout << i << endl;
                return 0;
            }
            if (op2.find(x) != op2.end()) {
                cout << i;
                return 0;
            }
        } else {
            op2.insert(x);
            if (op2.size() > 1) {
                cout << i;
                return 0;
            }
            if (op1.find(x) != op1.end()) {
                cout << i;
                return 0;
            }
        }
 
    }
    cout << -1;
    return 0;
}


发表于 2023-10-01 22:59:29 回复(1)
示例2不是只有三个盒子吗?解释中4号盒子怎么来的?
发表于 2023-10-07 16:18:19 回复(1)
发表于 2023-09-07 18:46:13 回复(0)
基于python的:
n,m = map(int,input().split())
op1 = set()
op2 = set()
flag = False
for k in range(m):
    t,x = map(int,input().split())
    if t == 1 and (x-1) not in op1:
        op1.add((x-1))
    if t == 2 and (x-1) not in op2:
        op2.add((x-1))
    if len(op1)==n&nbs***bsp;len(op2) > 1&nbs***bsp;((x-1) in op1 and (x-1) in op2):
        flag = True
        print(k+1)
        break
if not flag:
    print(-1)


发表于 2024-11-30 19:35:09 回复(0)
import java.util.Scanner;
public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt(), m = sc.nextInt();
        int[] a = new int[n+5];
        int[] b = new int[3];
        int[] p = new int[m+5];
        int[] x = new int[m+5];
        for (int i = 1; i <= m; i++) {
            p[i] = sc.nextInt();
            x[i] = sc.nextInt();
        }
        for (int i = 1; i <= m; i++) {
            if ((a[x[i]] & p[i]) == 0) {
                ++b[p[i]];
                a[x[i]] |= p[i];
                if (b[1] == n || b[2] == 2 || a[x[i]] == 3) {
                    System.out.print(i);
                    System.exit(0);
                }
            }
        }
        System.out.print(-1);
    }
}

发表于 2024-11-26 21:35:23 回复(0)
import java.util.*;
import java.io.*;

// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
    public static void main(String[] args) throws Exception {
        BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
        String[] str = bf.readLine().split(" ");
        int n = Integer.parseInt(str[0]);
        int m = Integer.parseInt(str[1]);

        Set<Integer> emptyBox = new HashSet<>();
        for(int i=1;i<=n;i++){
            emptyBox.add(i);
        }

        for(int i=0;i<m;i++){
            str = bf.readLine().split(" ");
            int op = Integer.parseInt(str[0]);
            int x = Integer.parseInt(str[1]);
            if(op==1){
                emptyBox.remove(x);
                if(emptyBox.isEmpty()){
                    System.out.println((i+1));
                    return;
                }
            }
            else{
                if(emptyBox.contains(x)){
                    emptyBox=new HashSet<>();//这里不要clear,clear会挨个遍历集合元素并移除,时间复杂度高
                    emptyBox.add(x);
                }
                else{
                    //success
                    emptyBox=new HashSet<>();
                    System.out.println((i+1));
                    return;
                }
            }
        }
        System.out.println(-1);
    }
}

发表于 2024-09-08 14:48:21 回复(0)
我不明白这样错在哪呢?有没有大佬指点一下
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int n = in.nextInt();
        int k = in.nextInt();
        long[] a = new long[n];
        for(int i = 0; i < n; i++){
            a[i] = in.nextLong();
        }
        int start = 0, end = 0;
        long sum = 0;
        int max = -1;
        while(end < n){
            sum += a[end];
            while(sum > (long)(end - start + 1) * (long)k){
                sum -= a[start];
                start++;
            }
            if(sum == (long)(end - start + 1) * (long)k){
                max = Math.max(end - start + 1, max);
            }
            end++;
           
        }
        System.out.println(max);
    }
}

发表于 2024-08-23 20:01:43 回复(0)
#include <iostream>
#include<map>
using namespace std;

int main() {
    int n,m;//n个盒子m次操作
    cin>>n>>m;

    map<int,int> cnmap;
    cnmap[0]=0;

    int res=0;

    int a,b;
    for(int i=1;i<=m;i++){//m次操作
        cin>>a>>b;
        if(cnmap.count(b));//如果已有记录
        else{//如果没有记录,那么记录下来盒子的数字,并且res加一
            cnmap[b]=1;
            res+=1;
            if(res==n){//如果加上这次后达成了,那么输出这时的次数并结束程序
                cout<<i;
                return 0;
            }
        }
    }
    if(res<n){//如果迟迟到结束都没有达成条件,那么输出-1
        cout<<-1;
        return 0;
    }

}
编辑于 2024-03-09 10:51:09 回复(0)
用上面大佬的思路写了个BitSet版本的。
其实这题的数据不大,BitSet没有必要。

import java.util.BitSet;
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int n = in.nextInt();
        int m = in.nextInt();
        BitSet bit1 = new BitSet(n);//至少有一个小球的盒子的集合
        int res = 0;
        for (int i = 0; i < m; i++) {
            res++;
            int t = in.nextInt();
            int b = in.nextInt();
            BitSet bit2 = new BitSet(n);
            if (t == 1) {
                //如果是1,就把bit1的第b位设置为true
                bit1.set(b - 1);
            } else {
                //如果是2,就把bit2的第b位设置为true
                //稍后取反
                bit2.set(b - 1);
            }
            
            //如果bit2不为0,说明有一个第二种操作,除了bit2中的那一个盒子,别的盒子至少都被放了一个小球
            //将bit2取反后就是所有至少有一个小球的盒子,用与操作更新到bit1中。
            if (bit2.cardinality() != 0 ) {
                bit2.flip(0, n);
                bit1.or(bit2);
            }
            if (bit1.cardinality() == n) {
                break;
            }
        }
        System.out.println(bit1.cardinality() == n ? res : -1);
    }
}

编辑于 2024-03-03 09:59:08 回复(0)
大一孩子都能看得懂的代码,这里直接统计未被放入球的盒子个数
#include <iostream>
using namespace std;
 
intmain() {
    intn, m;
    cin >> n >> m;
    int* a = newint[100000];
    for(inti = 0; i < n; i++)
        a[i] = 0;
    intt, x;
    intmei2 = -1;
    intsum = n;
    for(inti = 0; i < m; i++) {
        cin >> t >> x;
        if(t == 1) {
            if(a[x - 1] != 1) { //1表示放过了
                a[x - 1] = 1;
                sum--;
                //cout << x - 1 << endl;
            }
            if(sum == 0) {
                cout << i + 1;
                break;
            }
        }
        if(t == 2) {
            if(a[x - 1] == 1) {
                cout << i + 1;
                sum = 0;
                break;
            } else{
                if(mei2 == -1) {
                    for(intj = 0; j < n; j++)
                        a[j] = 1;
                    a[x - 1] = 0;
                    sum = 1;
                    mei2 = x;
                }
            }
        }
    }
    if(sum != 0)cout << -1;
}

发表于 2023-10-30 00:06:21 回复(0)
#include <bits/stdc++.h>
using namespace std;
#define IO ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
typedef long long ll;

int n,m;
int t[100005],x[100005],c[100005];
bool check(int len)
{
    for(int i=1;i<=n;i++)c[i]=0;
    for(int i=1;i<=len;i++)
    {
        if(t[i]==1)
        {
            c[x[i]]++;
            c[x[i]+1]--;
        }else 
        {
            c[1]++;
            c[n+1]--;
            c[x[i]]--;
            c[x[i]+1]++;
        }
    }
    int ans=0;
    for(int i=1;i<=n;i++)c[i]+=c[i-1],ans+=c[i]>=1;
    //cout<<len<<" "<<ans<<"\n";
    return ans==n;
}
void solve()
{
    cin>>n>>m;
    for(int i=1;i<=m;i++)cin>>t[i]>>x[i];
    int l=1,r=m,ans=-1;
    while(l<=r)
    {
        int mid=(l+r+1)/2;
        if(check(mid))
        {
            r=mid-1;
            ans=mid;
        }else l=mid+1;
    }
    cout<<ans;
}
int main()
{
    IO;
    solve();
    return 0;
}
发表于 2023-10-16 17:05:07 回复(0)

傻子用二分做的

n, m = map(int, input().split())
ord = []
for _ in range(m):
    t, x = map(int, input().split())
    ord.append((t, x))

def canSatisfied(mid: int):
    diff = [0] * (n + 1)
    type1 = set()
    for t, x in ord[:mid]:
        x -= 1
        if t == 1:
            type1.add(x)
        else:
            diff[0] += 1
            diff[x] -= 1
            diff[x + 1] += 1
            diff[n] -= 1
    acc = 0
    for i in range(n):
        acc = acc + diff[i]
        if acc == 0 and i not in type1:
            return False
    return True


l, r = 1, m
while l < r:
    mid = (l + r) // 2
    if canSatisfied(mid):
        r = mid
    else:
        l = mid + 1
if canSatisfied(l):
    print(l)
else:
    print(-1)
发表于 2023-09-26 22:40:20 回复(0)
n, m = map(int, input().split())
lst = [0] * (n + 1)
flag = 0
res = 0
for i in range(1, m + 1):
    t, x = map(int, input().split())
    if flag != 0:
        if t == 2 and x != flag:
            print(i)
            break
        if t == 1 and x == flag:
            print(i)
            break
    else:
        if t == 1:
            if lst[x] == 0:
                res += 1
                lst[x] = 1
                if res == n:
                    print(i)
                    break
        else:
            if lst[x] == 1:
                print(i)
                break
            flag = x
else:
    print(-1)
发表于 2023-09-12 23:47:13 回复(0)