自学内容网 自学内容网

51.哀家要长脑子了!

1.P1003 [NOIP2011 提高组] 铺地毯​​​​​​ 

重复 模拟 要求覆盖在最上面的地毯编号,用四个数组abgk分别记录地毯起点的左下角横纵坐标,地毯的长度宽度,输入的坐标x y 当它满足大于等于左下角坐标 并且 小于等于 地毯左下角横纵坐标的时候,就表示它在这个地毯上了 一直遍历完所有输入的地毯,最后就是覆盖在最上面的地毯

C++版本

#include<iostream>
using namespace std;

const int N = 1e6+10;
int a[N], b[N], g[N], k[N];

int main(){
    
    
    int n;
    cin >> n;
    for(int i = 1; i <= n; i++)
        cin >> a[i] >> b[i] >> g[i] >> k[i];
    
    int x,y;
    cin >> x >> y;
    
    int res = -1;
    for(int i = 1; i <= n; i++)
        if(x >= a[i] && y >= b[i] && x <= a[i]+g[i] && y <= b[i]+k[i])
            res = i;
    
    cout << res;
    
    return 0;
}

Java版本

import java.util.Scanner;

public class Main{

    static final int N = (int)1e6 + 10;
    static int[] a = new int[N];
    static int[] b = new int[N];
    static int[] g = new int[N];
    static int[] k = new int[N];

    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);

        int n = sc.nextInt();
        for(int i = 0; i < n; i++){
            a[i] = sc.nextInt();
            b[i] = sc.nextInt();
            g[i] = sc.nextInt();
            k[i] = sc.nextInt();
        }

        int x = sc.nextInt();
        int y = sc.nextInt();

        int res = -1;
        for(int i = 0; i < n; i++)
            if(x>=a[i] && y>=b[i] && x<=a[i]+g[i] && y<=b[i]+k[i])
                res = i + 1;

        System.out.println(res);
    }
}
2.P1007 独木桥 

 其实一个点下桥的最近距离就是转头直接下去,最远就是走到对面去,但因为题目要求相遇要转身给了干扰,但是,其实也还是可以看成相遇的时候不用转身继续往对面走,因为继续走不转身相当于对面的士兵帮你把你自己转身之后的路走了,这样子就简化了。

C++版本

#include<iostream>
using namespace std; 

int main(){
    int l;
    cin >> l;
    int n;
    cin >> n;
    int ans = 0, res = 0;
    for(int i = 0; i < n; i++){
        int a;
        cin >> a;
        
        ans = max(max(l-a+1, a), ans);
        res = max(min(l-a+1, a), res);
    }
    
    cout << res << " " << ans;
    
    return 0;
}

Java版本

import java.util.Scanner;
public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);

        int l = sc.nextInt();
        int n = sc.nextInt();


        int max = 0;
        int min = 0;

        for (int i = 0; i < n; i++) {
            int a = sc.nextInt();

            max = Math.max(Math.max(l+1-a, a), max);
            min = Math.max(Math.min(l+1-a, a), min);
        }

        System.out.println(min + " " + max);
    }
}
3.P1008 [NOIP1998 普及组] 三连击 

哎呀,其实挺好想到的,但是我还是想不到。。。。。

注意百位数枚举到3就好了,再大就溢出来了 

C++版本

#include<iostream>
using namespace std;

int main(){
    for(int i = 1; i <= 3; i++){  //百位数
        for(int j = 1; j <= 9; j++){  //十位数
            for(int k = 1; k <= 9; k++){  //个位数
                if(i == k || j == i || k == j) continue;  //跳过相同的
                
                int a = i*100 + j*10 + k;
                int b = a * 2;
                int c = a * 3;
                
                if(c >= 1000) return 0;
                
                int l = b/100, m = b/10%10, n = b%10;  //取出每一位上的数
                int o = c/100, p = c/10%10, q = c%10;
                
                if(i+j+k+l+m+n+o+p+q == 1+2+3+4+5+6+7+8+9 && //一个数字用一次
                   i*j*k*l*m*n*o*p*q == 1*2*3*4*5*6*7*8*9)
                    cout << a << " " << b << " " << c << endl;
                   
            }
        }
    }
    return 0;
}

Java版本

public class Main{
    public static void main(String[] args){
        
        for(int i = 1; i <= 3; i++){
            for(int j = 1; j <= 9; j++){
                for(int k = 1; k <= 9; k++){
                    if(i == j || j == k || i == k) continue;
                    
                    int a = i*100 + j*10 + k;
                    int b = a * 2;
                    int c = a * 3;
                    
                    if(c >= 1000) break;
                    
                    int l = b/100, m = b/10%10, n = b%10;
                    int o = c/100, p = c/10%10, q = c%10; 
                    
                    if(i+j+k+l+m+n+o+p+q == 1+2+3+4+5+6+7+8+9 &&
                       i*j*k*l*m*n*o*p*q == 1*2*3*4*5*6*7*8*9)
                        System.out.println(a + " " + b + " " + c);
                }
            }
        }
    }
}
 4.220. 存在重复元素 III - 力扣(LeetCode)

首先用的双重for循环还想着简简单单。。

可以用set(滑动窗口和查找,但是桶排序效率更高

C++版本

class Solution {
public:
    bool containsNearbyAlmostDuplicate(vector<int>& nums, int k, int t) {
        set<long> st;
        for (int i = 0; i < nums.size(); i++) {
            auto lb = st.lower_bound((long)nums[i] - t);
            if (lb != st.end() && *lb <= (long)nums[i] + t) return 1;
            st.insert(nums[i]);
            if (i >= k) st.erase(nums[i - k]);
        }
        return 0;
    }
};

Java版本

class Solution {
    public boolean containsNearbyAlmostDuplicate(int[] nums, int indexDiff, int valueDiff) {
        int n = nums.length ;
        TreeSet<Long> ts = new TreeSet<>();
        for(int i = 0; i < n; i++){
            Long val = nums[i]*1L;
            // 小于等于nums[i] 的最大元素
            Long left = ts.floor(val);
            // 大于等于nums[i] 的最小元素
            Long right = ts.ceiling(val);

            if(left!=null && val - left <= valueDiff) return true;
            if(right!=null && right - val <= valueDiff) return true;

            ts.add(val);

            if(i >= indexDiff) ts.remove(nums[i-indexDiff]*1L);
        }
        return false;
    }
}
Java中的TreeSeet 

 有序、唯一

  1.创建TreeSet
import java.util.TreeSet

TreeSet<Integer> ts = new TreeSet<>();
  2.添加元素
ts.add(要添加的元素);
   3.删除元素
ts.remove(要删除的元素);
  4.查找元素
boolean chazhao = ts.contains(要查找的元素值);
  5.获取子集
// 获取从 1 到 5 的子集
TreeSet<数据类型> subSet = (TreeSet<数据类型>) ts.subSet(1, 5);
  6.获取头尾元素
// 获取最小元素
接收 = ts.first();

// 获取最大元素
接收 = ts.last();
  7.获取上下界元素
// 获取大于等于val 的最小元素
接收 = ts.ceiling(val);

// 获取小于等于val 的最大元素
接受 = ts.floor(val);
  8.获取下一个元素和前一个元素
// 获取 val 的下一个元素
接收 = ts.higher(val);

// 获取 val 的前一个元素
接收 = ts.lower(val);

原文地址:https://blog.csdn.net/m0_73072282/article/details/142769660

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!