大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__':