[编程题]矩形重叠
平面内有n个矩形, 第i个矩形的左下角坐标为(x1[i], y1[i]), 右上角坐标为(x2[i], y2[i])。
如果两个或者多个矩形有公共区域则认为它们是相互重叠的(不考虑边界和角落)。
请你计算出平面内重叠矩形数量最多的地方,有多少个矩形相互重叠。
输入描述:
输入包括五行。
第一行包括一个整数n(2 <= n <= 50), 表示矩形的个数。
第二行包括n个整数x1[i](-10^9 <= x1[i] <= 10^9),表示左下角的横坐标。
第三行包括n个整数y1[i](-10^9 <= y1[i] <= 10^9),表示左下角的纵坐标。
第四行包括n个整数x2[i](-10^9 <= x2[i] <= 10^9),表示右上角的横坐标。
第五行包括n个整数y2[i](-10^9 <= y2[i] <= 10^9),表示右上角的纵坐标。
输出描述:
输出一个正整数, 表示最多的地方有多少个矩形相互重叠,如果矩形都不互相重叠,输出1。
输入
2
0 90
0 90
100 200
100 200
输出
2
/*
无论何种情况,重叠区域也是四条边组成。
而且是取自与n的矩形中的四条。
所以遍历边的交点即可。
*/
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int n = in.nextInt();
int[] x1 = new int[n];
int[] y1 = new int[n];
int[] x2 = new int[n];
int[] y2 = new int[n];
int xmin = Integer.MAX_VALUE;
int xmax = Integer.MIN_VALUE;
int ymin = Integer.MAX_VALUE;
int ymax = Integer.MIN_VALUE;
for (int i = 0; i < n; i++)
x1[i] = in.nextInt();
for (int i = 0; i < n; i++)
y1[i] = in.nextInt();
for (int i = 0; i < n; i++)
x2[i] = in.nextInt();
for (int i = 0; i < n; i++)
y2[i] = in.nextInt();
int ans = 0;
int cnt = 0;
for (int x : x1)
for (int y : y1) {
for (int i = 0; i < n; i++) {
if (x >= x1[i] && x < x2[i] && y >= y1[i] && y < y2[i])
cnt++;
}
if (cnt > ans)
ans = cnt;
cnt = 0;
}
System.out.println(ans);
}
}
[编程题]牛牛的闹钟
牛牛总是睡过头,所以他定了很多闹钟,只有在闹钟响的时候他才会醒过来并且决定起不起床。从他起床算起他需要X分钟到达教室,上课时间为当天的A时B分,请问他最晚可以什么时间起床
输入描述:
每个输入包含一个测试用例。
每个测试用例的第一行包含一个正整数,表示闹钟的数量N(N<=100)。
接下来的N行每行包含两个整数,表示这个闹钟响起的时间为Hi(0<=A<24)时Mi(0<=B<60)分。
接下来的一行包含一个整数,表示从起床算起他需要X(0<=X<=100)分钟到达教室。
接下来的一行包含两个整数,表示上课时间为A(0<=A<24)时B(0<=B<60)分。
数据保证至少有一个闹钟可以让牛牛及时到达教室。
输出描述:
输出两个整数表示牛牛最晚起床时间。
输入
3
5 0
6 0
7 0
59
6 59
输出
6 0
把时间都转换为分钟计数,上课时间-路上时间得到最晚起床时间,把所有闹钟时间排序后,二分查找最晚起床时间。
import java.util.*;
public class Main{
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int h=0,m=0;
int[] a = new int[n];
for(int i=0;i<n;i++){
h = sc.nextInt();
m = sc.nextInt();
a[i] = h*60+m;
}
int t = sc.nextInt();
h = sc.nextInt();
m = sc.nextInt();
int p = h*60+m-t;
Arrays.sort(a);
t = Arrays.binarySearch(a,p);
if(t <0) t = -(t+2);
h = a[t]/60;
m = a[t]%60;
System.out.print(h+" "+m);
}
}
[编程题]牛牛的背包问题
牛牛准备参加学校组织的春游, 出发前牛牛准备往背包里装入一些零食, 牛牛的背包容量为w。
牛牛家里一共有n袋零食, 第i袋零食体积为v[i]。
牛牛想知道在总体积不超过背包容量的情况下,他一共有多少种零食放法(总体积为0也算一种放法)。
输入描述:
输入包括两行
第一行为两个正整数n和w(1 <= n <= 30, 1 <= w <= 2 * 10^9),表示零食的数量和背包的容量。
第二行n个正整数v[i](0 <= v[i] <= 10^9),表示每袋零食的体积。
输出描述:
输出一个正整数, 表示牛牛一共有多少种零食放法。
输入
3 10
1 2 4
输出
8
说明
三种零食总体积小于10,于是每种零食有放入和不放入两种情况,一共有2*2*2 = 8种情况。
问题描述
其中,表示第i个放入还是不放入,设state(i,w)表示i个零食放入背包小于等于W的个数,把state(i,w)分解,可以分解为两个情况:
1、是第i个不放入时,前i-1个零食放入背包小于等于W的个数即state(i-1,w);
2、是在第i个放入的情况下,前i-1个零食放入背包体积小于等于W-v[i]的个数即state(i-1,w-v[i]);
即 state(i,w) = state(i-1,w) + state(i-1,w-v[i])
边界条件:i = 1时,state(1,w1) 此时如果w1 >0 且v[1]<=w1,state(1,w1) = 2,即有可放入和不放入两种;
i = 1 时,swate(1,w1)此时如果w1 >0且v[1] > w1,state(1,w1)=1,即只有不放入一种;
如果state(i,w)中出现w<=0,则state(i,w)=0;
例子:零食体积1 2 4,w=10
则 state(3,10) = state(2,10) + state(2,6)
= state(1,10) + state(1,8) + state(1,6) + state(1,4)
= 2 + 2 + 2 + 2 = 8
采用递归解法:AC率80%
#include<iostream>
#include<vector>
using namespace std;
int f(int n1, int n2,vector<int> &num)
{
if(n2 <= 0)
{
return 0;
}
if(n1 == 1)
{
if(num[n1] <= n2)
{
return 2;
}
else
{
return 1;
}
}
return f(n1-1,n2,num) + f(n1 - 1,n2-num[n1],num);
}
int main()
{
int n1,sum;
cin >> n1 >> sum;
vector<int> res(n1 + 1);
for(int i=1;i<=n1;i++)
{
cin >> res[i];
}
cout << f(n1,sum,res) << endl;
return 0;
}