昨晚原本准备在宿舍打cf的,结果吵吵闹闹的,也没打成,头也晕晕的,当时看了只看了第一个题,越想越麻烦,最后竟然陷入了误区,半小时也没解,虽然注册了,一发也没交。。。
Dima and Seryozha live in an ordinary dormitory room for two. One day Dima had a date with his girl and he asked Seryozha to leave the room. As a compensation, Seryozha made Dima do his homework.
The teacher gave Seryozha the coordinates of n distinct points on the abscissa axis and asked to consecutively connect them by semi-circus in a certain order: first connect the first point with the second one, then connect the second point with the third one, then the third one with the fourth one and so on to the n-th point. Two points with coordinates (x1, 0) and (x2, 0) should be connected by a semi-circle that passes above the abscissa axis with the diameter that coincides with the segment between points. Seryozha needs to find out if the line on the picture intersects itself. For clarifications, see the picture Seryozha showed to Dima (the left picture has self-intersections, the right picture doesn't have any).
Seryozha is not a small boy, so the coordinates of the points can be rather large. Help Dima cope with the problem.
The first line contains a single integer n (1 ≤ n ≤ 103). The second line contains n distinct integers x1, x2, ..., xn ( - 106 ≤ xi ≤ 106) — the i-th point has coordinates (xi, 0). The points are not necessarily sorted by their x coordinate.
In the single line print "yes" (without the quotes), if the line has self-intersections. Otherwise, print "no" (without the quotes).
4 0 10 5 15
yes
4 0 15 5 10
no
The first test from the statement is on the picture to the left, the second test is on the picture to the right.
题目意思很好懂,就看你怎么去建立模型,简化计算。早上起床灵光一闪。如果要是两线相交的话,必然存在公共区域。可以直接枚举任意的两条线,时间复杂度为O(10^6)。具体实现见代码。
AC代码:
#include<iostream>
#include<cstring>
#include<string>
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
int a[1005];
int main()
{
int n,i,j;
while(cin>>n)
{
for(i=0;i<n;i++)
cin>>a[i];
int flag =0,mi1,mi2,ma1,ma2;
for(i=0;i<n-1;i++)
{
mi1=min(a[i],a[i+1]);
ma1=max(a[i],a[i+1]); //第一条线mi1-ma1 第二条线mi2-ma2
for(j=i+2;j<n-1;j++)
{
mi2=min(a[j],a[j+1]);
ma2=max(a[j],a[j+1]);
if((mi2>mi1&&mi2<ma1&&ma2>ma1)||(mi2<mi1&&ma2>mi1&&ma2<ma1)) //相交
{
flag=1;
break;
}
}
if(flag) break;
}
if(flag) puts("yes");
else puts("no");
}
return 0;
}
/*
7
4 6 7 1 2 3 5
*/
这个题目如果看懂的话,相当easy,关键是要看懂。。当时第一题没搞出来就直接没看了。前面给你n个串,在每个串前面加上<3后面加上>3链接在一起。最后在链接好的串里插入任意字段。再给你一个串,问满足条件否?
开始原先想的就是先比较<3然后跟串一个一个挨着比较,每比较完一个,就再匹配一个<3。具体实现见代码。最后还需要匹配一个<3.
代码:
#include<iostream>
#include<cstring>
#include<string>
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
string a[100005];
string p;
int main()
{
int n,i,j;
while(cin>>n)
{
for(i=0;i<n;i++)
cin>>a[i];
cin>>p;
int flag=0;
int fla=0;
int s=0,t=0;
for(i=0;i<p.length();i++)
{
if(s==n)
{
fla=1;
break;
}
if(flag==0) //先匹配<
{
if(p[i]=='<')
flag=1;
}
else if(flag==1) //匹配3
{
if(p[i]=='3')
flag=2;
}
else
{
if(p[i]==a[s][t]&&t==a[s].length()-1)
{
s++;
t=0;
flag=0; //匹配一个串后需要重新匹配<3
}
else if(p[i]==a[s][t])
{
t++;
}
}
}
//cout<<s<<" "<<i<<endl;
flag=0;
if(fla) //匹配最后的<3
{
for(j=i;j<p.length();)
{
if(flag==0) //匹配<
{
if(p[j]=='<')
flag=1;
j++;
}
else if(flag==1) //匹配3
{
if(p[j]=='3')
{
fla=2;
break;
}
j++;
}
}
}
if(fla==2) puts("yes");
else puts("no");
}
return 0;
}
/*
3
i
love
you
<3i<3lo<3ve<3y<<<<<<<ou3<3
1
a
<3a<2
2
a
i
<3ai<3
*/
//46MS
后来仔细想可以先把满足条件最简单的串构造出来,再匹配。估计是用了string +,时间有点多。
代码:
#include<iostream>
#include<cstring>
#include<string>
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
string a;
string p;
string tmp;
int main()
{
int n,i,j;
while(cin>>n)
{
a="<3"; //先加在最前面
for(i=0;i<n;i++)
{
cin>>tmp;
a=a+tmp;
a+="<3"; //每一串后面都加一个<3
}
//现在a串是最短长度的解
cin>>p;
int t=0,len=a.length();
for(i=0;i<p.length();i++)
{
if(t==len) break;
if(p[i]==a[t])
t++;
}
if(t==len) puts("yes");
else puts("no");
}
return 0;
}
//1684 ms
然后算法设计老师讲的一个题目蛮有意思的,给你两根长短不同,粗细不均匀的绳子,我们仅仅知道每根绳子烧完需要1h,问怎么才能使得两根绳子都烧完,且刚好用时45min.
think........
用火机先点燃一根绳子的两头和另一根绳子的一头。这样用时30min,之后将剩下的绳子的另一头点燃。
还有一个题目是关于公倍数的,求解%3=a,%5=b,%7=c,这样的最小的正整数t,我们假设t=(5*7*s1)*a+(3*7*s2)*b+(3*5*s3)*c.我们只需要保证5*7*s1%3=1即可,因此s1取2,依次s2=1,s3=1。我们可以将他的一个解找到,然后+lcm(3,5,7)*k就是他的通解了,就可以求解了。