大M布置给小M一个题目:首先给出n个在横坐标上的点,然后连续的用半圆连接他们:首先连接第一个点与第二点(以第一个点和第二点作为半圆的直径)。然后连接第二个第三个点,直到第n个点。现在需要判定这些半圆是否相交了,在端点处相交不算半圆相交。如下图所示。
输入的第一行包含一个整数T (1 ≤ T ≤ 10)表示有T组样例。
每组样例的第一行是一个整数n (1≤n≤1000)。
接下来的一行输入有n个用空格隔开的不同的整数a1,a2,...,an (-1000000 ≤ ai ≤ 1000000),(ai,0)表示第i个点在横坐标的位置。
对于每个输入文件,输出T行。
每行输出"y"表示这些半圆有相交或者"n"。
2 4 0 10 5 15 4 0 15 5 10
y n
#include <bits/stdc++.h>
using namespace std;
bool F(int l1, int r1, int l2, int r2){
return (l2<r1 && l2>l1 && r2>r1) || (r2<r1 && r2>l1 && l2<l1);
}
int main(){
int T,n,l1,r1,l2,r2;
cin>>T;
while(T--){
cin>>n;
int a[n];
for(int i=0;i<n;i++)
cin>>a[i];
bool flag = true;
for(int i=2;i<n && flag;i++){
l1 = min(a[i], a[i-1]);
r1 = max(a[i], a[i-1]);
for(int j=i-2;j>0;j--){
l2 = min(a[j], a[j-1]);
r2 = max(a[j], a[j-1]);
if(F(l1, r1, l2, r2)){
flag = false;
break;
}
}
}
cout<<(flag?'n':'y')<<endl;
}
return 0;
} """"
找到规律本题不难,对连续的3个值p1,p2,p3
若p3 落在p1、p2中间,则p1、p2区间两侧不能再取值用flag[]=False标记,
否则,p1、p2构成的区间内不能再取值。
by the way:
本题 -1000000 ≤ ai ≤ 1000000,对每一个整数设置并修改flag 时空复杂度较高,
所以通过排序好的b 只对经过的点设置flag,没有经过的点设置flag是没意义的。
"""
if __name__ == "__main__":
T = int(input())
for _ in range(T):
n = int(input())
a = list(map(int, input().strip().split()))
if len(a) <= 3:
print('n')
continue
b = sorted(a)
flag = [True] * len(b) # 所有点都可取
ans = True # 初始设为没有相交点
p1, p2 = a[0], a[1]
for i in range(2, len(a)):
if flag[b.index(a[i])] == False: # 判断此点是否在之前标记为不可取
ans = False # 存在一个相交点,即停止遍历并输出结果
break
if min(p1, p2) < a[i] < max(p1, p2): # 更新区间外的flag为False
for j in range(0, b.index(min(p1, p2))):
flag[j] = False
for j in range(b.index(max(p1, p2)) + 1, len(b)):
flag[j] = False
else: # 更新区间内flag为False
for j in range(b.index(min(p1, p2)) + 1, b.index((max(p1, p2)))):
flag[j] = False
p1, p2 = p2, a[i]
print('n' if ans else 'y')
#include <stdio.h>
#include <stdlib.h>
int min(a,b){
return a < b ? a : b;
}
int max(a,b){
return a > b ? a : b;
}
int main() {
int T = 0;
scanf("%d", &T);
while(T--){
int n = 0;
scanf("%d", &n);
int circle[n-1][2];
int vec[n];
for(int i = 0; i < n;i++){
scanf("%d", &vec[i]);
}
for(int i = 0; i < n-1;i++){
circle[i][0] = min(vec[i],vec[i+1]);
circle[i][1] = max(vec[i],vec[i+1]);
}
int flag = 0;
for(int i = 0; i < n - 1; i++){
for(int j = 0; j < i;j++){
int l1 = circle[i][0], r1 = circle[i][1];
int l2 = circle[j][0], r2 = circle[j][1];
if((l1 < l2) && (r1 < r2) && (r1 > l2)){
flag = 1; break;
}
if((l1 > l2) && (l1 < r2) && (r1 > r2)){
flag = 1; break;
}
}
if(flag) break;
}
if(flag) {
printf("y\n");
}else {
printf("n\n");
}
}
return 0;
} import sys
group=int(input())#获取组数
for f in range(group):
num=int(input())#获取点数
points=list(map(int,input().split()))#坐标
flag=False
for n in range(num//2):#对于每个圆
cur_round=[points[2*n],points[2*n+1]]
# print(cur_round)
others=points[0:2*n]+points[2*n+2:]
# print(len(others))
for i in range(0,len(others),2):#对比每个圆是否只有一个点在其他圆内
# print(i)
# print(cur_round[0],others[i],others[i+1])
# print(cur_round[1],others[i],others[i+1])
if cur_round[0]>others[i] and cur_round[0]<others[i+1]:
flag=not flag
if cur_round[1]>others[i] and cur_round[1]<others[i+1]:
flag=not flag
if flag:
print("y")
break
if flag:
break
if flag:
continue
print("n") #include <bits/stdc++.h> // C++万能头文件
using namespace std;
static const auto io_sync_off = [](){ // lambda表达式
std::ios::sync_with_stdio(false); // 解除与scanf()等函数的同步
std::cin.tie(nullptr); // 解除cin和cout的绑定
return nullptr;
}();
int main() {
int T;
cin >> T;
while (T--) {
int n;
cin >> n;
map<int, vector<int>> mp; // 相同左边界的所有右边界
int pre, cur;
cin >> pre;
for (int i = 1; i < n; ++i) {
cin >> cur;
int l = min(pre, cur), r = max(pre, cur);
mp[l].push_back(r);
pre = cur;
}
if (n <= 2) {
cout << "n" << endl;
continue;
}
bool cross = false;
auto iter = mp.begin();
vector<int> prev = iter->second;
sort(prev.begin(), prev.end());
iter++;
while (iter != mp.end()) {
vector<int> curv = iter->second;
sort(curv.begin(), curv.end());
int left = iter->first;
int i = upper_bound(prev.begin(), prev.end(), left) - prev.begin();
if (i < prev.size()) { // prev[i] > left
int maxr = curv.back();
if (maxr > prev[i]) {
cross = true;
break;
}
}
prev = move(curv);
++iter;
}
if (cross) cout << "y" << endl;
else cout << "n" << endl;
}
return 0;
} while True:
try:
n = int(input())
for case in range(n):
m1 = int(input())
list1 = list(map(int,input().split()))
one = list()
for i in range(len(list1)):
if i <m1-1:
one.append((list1[i],list1[i+1]))
count = 0
flag = False
#print(one)
for i in one:
k1,k2 = i[0],i[1]
count+=1
for j in range(count,len(one)):
ppp = one[j]
p1,p2 = ppp[0],ppp[1]
if (min(k1,k2)<min(p1,p2) and max(k1,k2)>min(p1,p2) and max(k1,k2)<max(p1,p2))&nbs***bsp;(max(k1,k2)>max(p1,p2) and min(k1,k2)<max(p1,p2) and min(k1,k2)>min(p1,p2)):
flag =True
break
else:
continue
break
if flag == True:
print('y')
else:
print("n")
except:
break import java.util.*;
public class Main{
private static final int COUNT=6;
public static void main(String[] args){
Scanner sc=new Scanner(System.in);
while(sc.hasNext()){
int t=sc.nextInt();
for(int i=0;i<t;i++){
boolean bool=true;
int n=sc.nextInt();
TreeSet<Integer> set=new TreeSet<>();
int a=sc.nextInt();
set.add(a);
for(int j=1;j<n;j++){
int b=sc.nextInt();
set.add(b);
int max=Math.max(a,b);
int min=Math.min(a,b);
if(bool&&(max!=set.higher(min))&&!(min==set.first()&&max==set.last())){
bool=false;
}
a=b;
}
if(bool)
System.out.println("n");
else
System.out.println("y");
}
}
sc.close();
}
} //没想到暴力也能解答 一直以为有优化的解法
#include<iostream>
(720)#include<vector>
#include<algorithm>
using namespace std;
bool judge(vector<int> &v){
vector<vector<int>> cir;
for (int i = 0; i < v.size()-1; i++){
int L = min(v[i], v[i+1]);
int R = max(v[i], v[i+1]);
cir.push_back(vector<int> {L, R});
}
for (int i = 1; i < cir.size(); i++){
for (int j = 0; j < i; j++){
if (cir[i][0] < cir[j][0] && cir[i][1] < cir[j][1] && cir[i][1] > cir[j][0]){
return true;
}
else if(cir[i][1] > cir[j][1] && cir[i][0] < cir[j][1] && cir[i][0] > cir[j][0]){
return true;
}
}
}
return false;
}
int main(void){
int T;
cin>>T;
vector<int> v;
int n;
int num;
for (int i = 0; i < T; i++){
cin>>n;
if (n <= 2){
cout<<"n"<<endl;
continue;
}
v.clear();
for (int j = 0; j < n; j++){
cin>>num;
v.push_back(num);
}
if (judge(v))
cout<<"y"<<endl;
else
cout<<"n"<<endl;
}
return 0;
} T = int(input())
def low_low_bound(data,en,value):
st = 0
en-=1
while st<=en:
mid = (st+en)//2
if data[mid][1]<value:
st = mid + 1
else:
en = mid - 1
return en
for _ in range(T):
tmp = int(input())
data = list(map(int,input().split()))
re = []
for i in range(len(data)-1):
re.append((min(data[i],data[i+1]),max(data[i],data[i+1])))
re.sort(key = lambda x:(x[1],x[0]))
b = 'n'
for i in range(1,len(re)):
if b=='y':
break
j_max = low_low_bound(re,i,re[i][1])
#j_max = i-1
for j in range(j_max+1):
if re[i][0]<re[j][1] and re[i][0]>re[j][0]:
b = 'y'
break
print(b) 聪明的你一定想到了,第一次过了90+,肯定是卡的时间边界,那只需要把他改成C++就过了不需要优化哈哈我已经尽量简化计算了,但只要有两层循环就超时😓 if __name__=='__main__':