Vjudge题目杂集 (2)

二分查找

 

A. 查找

题目描述:

输入 n (n≤10^6) 个不超过 10^9的单调不减的(就是后面的数字不小于前面的数字)非负整数 a1​,a2​,…,an​,然后进行 m(m≤10^5) 次询问。
对于每次询问,给出一个整数 q(q≤10^9),要求输出这个数字在序列中第一次出现的编号,如果没有找到的话输出 -1 。

 

Input:

第一行 2 个整数 n 和 m,表示数字个数和询问次数。

第二行 n 个整数,表示这些待查询的数字。

第三行 m 个整数,表示询问这些数字的编号,从 1 开始编号。 

 

Output:

m 个整数表示答案。

 

示例:

输入:
11 3
1 3 3 3 5 7 9 11 13 15 15
1 3 6

输出:
1 -2 1

 

思路:

正常二分查找。

 

代码:

#include<iostream>
#include<bits/stdc++.h>
using namespace std;

int cac(vector<int> number, int x) {
    int left = 0, right = number.size() - 1, res = -1;
    while(left <= right){
        int mid = (left + right) / 2;
        if(number[mid] == x) {
            res = mid + 1;
            break;
        }
        else if(number[mid] < x) left = mid + 1;
        else right = mid - 1;
    }
    return res;
}

int main() {
    int n, m;
    cin >> n >> m;
    vector<int> number(n);
    vector<int> nums(m);
    for(int i = 0; i < n; i++)
        cin >> number[i];
    number.erase(unique(number.begin(), number.end()), number.end()); //unique函数将重复的元素移到容器末尾,配合erase函数删除则达到去重的功能
    for(int j = 0; j < m; j++){
        cin >> nums[j];
        cout << cac(number, nums[j]) << " ";
    }
    return 0;
}

 

B. 烦恼的高考志愿

题目描述:


现有 m (m≤100000) 所学校,每所学校预计分数线是ai​(ai​≤10^6)。有 n (n≤100000) 位学生,估分分别为 bi​ (bi​≤10^6)。


根据n位学生的估分情况,分别给每位学生推荐一所学校,要求学校的预计分数线和学生的估分相差最小(可高可低,毕竟是估分嘛),这个最小值为不满意度。求所有学生不满意度和的最小值。

 

Input:

第一行读入两个整数m,n。m表示学校数,n表示学生数。第二行共有m个数,表示m个学校的预计录取分数。第三行有n个数,表示n个学生的估分成绩。

 

Output:

一行,为最小的不满度之和。

 

示例:

输入:
4 3
513 598 567 689
500 600 550

输出:
32

 

思路:

在二分查找时,每次选出最小的差值。

 

代码:

#include<iostream>
#include<bits/stdc++.h>
using namespace std;

int cac(vector<int> school, int b) {
    int left = 0, right = school.size() - 1, res = INT_MAX;
    while(left <= right){
        int mid = (left + right) / 2;
        if(school[mid] == b) {
            res = 0;
            break;
        }
        else if(school[mid] > b) {
            right = mid - 1;
            res = min(res, abs(school[mid] - b));
        }
        else {
            left = mid + 1;
            res = min(res, abs(school[mid] - b));
        }    
    }
    return res;
}

int main() {
    int m, n, ans = 0;
    cin >> m >> n;
    vector<int> school(m);
    vector<int> student(n);
    for(int i = 0; i < m; i++)
        cin >> school[i];
    sort(school.begin(), school.end());
    for(int i = 0; i < n; i++) {
        cin >> student[i];
        ans += cac(school, student[i]);    
    }
    cout << ans;
    return 0;
}

 

C. 银行贷款

题目描述:

当一个人从银行贷款后,在一段时间内他(她)将不得不每月偿还固定的分期付款。这个问题要求计算出贷款者向银行支付的利率。假设利率按月累计。

 

Input:

三个用空格隔开的正整数。

第一个整数表示贷款的原值,第二个整数表示每月支付的分期付款金额,第三个整数表示分期付款还清贷款所需的总月数。

 

Output:

一个实数,表示该贷款的月利率(用百分数表示),四舍五入精确到 0.1%。

 

示例:

输入:
1000 100 12

输出:
2.9

 

思路:

本题相较前两题考虑更多。

每年钱应为num * (1 + x) - m; 即每年的利率后本金减去需缴付的月资金,若本金耗尽则可还清,反之不可。

上网查询,国家规定月利率不得大于2.5% 则从 0 - 500 开始查找符合题意的情况。

 

代码:

#include<iostream>
#include<bits/stdc++.h>
using namespace std;

bool cac(double x, int n, int m, int d) {
    double num = n;
    for(int i = 0; i < d; i++){
        num += num * x;
        num -= m;
    }
    if(num <= 0) return true;
    else return false;
}

int main() {
    int n, m, d;
    cin >> n >> m >> d;
    double left = 0, right = 500, mid;
    for(int i = 0; i < 100; i++){
        mid = (left + right) / 2;
        if(cac(mid / 100, n, m, d)) left = mid;
        else right = mid;
    }
    printf("%.1lf", left);
    return 0;
}

 

上一篇:新生45场


下一篇:如何安装部署Memcached?