题目+我的答案+我的考后感想
音阶(ljestvica/1S/64M)
【题目描述】
Veronica进入了音乐学院。她收到了一张只有音符没有注释的乐谱,需要认出乐谱中用到的音阶。在本题中,我们只用到了两种最常用的(而且也是学校最先教的)音阶:A小调和C大调。这并不是说这两个音阶比其他大调、小调更简单或基础, 所有的小调和大调都是差不多的。
现代音乐中一个八度有12个音(A, A#, B, C, C#, D, D#, E ,F, F#, G, G#),A小调和C大调也是用这12个音组成。A小调是一组有序的七个音{A,B,C,D,E,F,G},C大调是{C,D,E,F,G,A,B}。
注意,这两个音阶用到的音是一样的。那区别在哪?确定一个音阶,重点不仅在用到了什么音,还有他们的用法。主音(一个音阶的第一个音), 下属音(第四个音),属音(第五个音)在一个音阶中是重音的首选。在A小调中就是A、D、E,在C大调中就是C、F、G。我们把这些音叫main tones。
大调和小调有什么不同呢?比方说,A小调的中音(第三个音)比主音高三个半音,C大调的中音比主音高四个半音。总之,差别就在于两个相邻的音的距离。这使小调听起来伤感,大调听起来喜庆。
现在你要写一个程序判断这首曲子是用A小调写的还是用C大调写的。可以数在重音(每小节的第一个音)中是A小调的main tones多还是C大调的main tones多。如果main tones数相同,若最后一个音是A小调的main tones,这首曲子就是A小调,否则就是C大调。
比如说,现在来判断著名的旋律“你在睡觉吗?”;
CD|EC|CD|EC|EF|G|EF|G|GAGF|EC|GAGF|EC|CG|C|CG|C
字符“|”把每个小节隔开了,所以这个旋律的重音依次是:C,E,C,E,E,G,E,G,G,E,G,E,C,C,C,C。有10个C大调的main tones,6个A小调的main tones,所以这个旋律是C大调的。
【输入格式】
输入文件仅一行, 包含一个序列(最短为5, 最长100), 每个字母都包含在{“A”, “B”, “C”, “D”, “E”, “F”, “G”, “|”} 中。 其中”|” 将每小节分开, 且不会出现在序列的开头或结尾。
【输出格式】
输出文件仅一行,为” C-dur “ (C大调) 或 “ A-mol” (A小调)。
【输入1】
AEB|C
【输出1】
C-dur
【输入2】
CD|EC|CD|EC|EF|G|EF|G|GAGF|EC|GAGF|EC|CG|C|CG|C
【输出2】
C-dur
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
using namespace std ;
int main()
{
freopen("ljestvica.in","r",stdin);
freopen("ljestvica.out","w",stdout);
string st;
cin>>st;
bool flag=true;
int a=0,c=0,len=st.size();
for (int i=0;i<len;i++)
{
if (flag)
{
if (st[i]=='A'||st[i]=='D'||st[i]=='E')
a++;
if (st[i]=='C'||st[i]=='F'||st[i]=='G')
c++;
flag=false;
}
if (st[i]=='|')
flag=true;
}
if (a<c) cout<<"C-dur"<<endl;
if (a>c) cout<<"A-mol"<<endl;
if (a==c)
if (st[len-1]=='A'||st[len-1]=='D'||st[len-1]=='E')
cout<<"A-mol"<<endl;
else cout<<"C-dur"<<endl;
return 0;
}
这题其实就是一道水题,没有什么好解释的。但是我被这题卡了一小会儿,还是影响了后面的作答。主要是因为编译器的原因,这个编译器不完全,有bug。无论是什么程序都编译不了。搞得我还以为是因为我自己太久没编程序或是自己太粗心的原因有一些小细节没发现,结果搞了很久。最后还是凭着蹩脚的英文水平看出了问题所在。重新下载了编译器,浪费了大量时间。所以我觉得考前调试编译器也是一个重要的习惯。【血的教训,很不爽
=========================================================
波老师(teacher/1S/64M)
【题目描述】
波波老师是一个地理老师。有一天他上课的时候,他在地图上标记了N个点,第i个点在点(Xi,Yi)。他想知道,是否存在四个点(A,B,C,D)(A<B,C<D,A≠C或者B≠D),使AB之间的曼哈顿距离和CD之间的曼哈顿距离相等。
如果存在这样的四个点,输出YES,否则输出NO。
【输入格式】
输入文件第一行是一个T(T≤50),表示有T组数据。
接下来有T组数据,每组数据第一行是两个整数N,M,表示点的个数以及点的坐标的边界,然后有N行,第i行有两个整数Xi,Yi表示第i个点的坐标(Xi,Yi)(0≤Xi,Yi≤M)
【输出格式】
输出文件有T行,每一行为YES或者NO。
【输入】
2
3 10
1 1
2 2
3 3
4 10
8 8
2 3
3 3
4 4
【输出】
YES
NO
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std ;
struct Tnode
{
int x,y;
};
Tnode node[100005];
bool cmp(Tnode a,Tnode b)
{
return a.x<b.x||(a.x==b.x&&a.y<b.y);
}
long long sqr(int x)
{
return x*x;
}
long long len(Tnode a,Tnode b)
{
return sqr(b.x-a.x)+sqr(b.y-a.y);
}
int main()
{
freopen("teacher.in","r",stdin);
freopen("teacher.out","w",stdout);
int T;
cin>>T;
for (int t=0;t<T;t++)
{
int n,m;
cin>>n>>m;
for (int i=0;i<n;i++)
cin>>node[i].x>>node[i].y;
sort(node,node+n,cmp);
bool flag=false;
for (int i=0;i<n-1&&!flag;i++)
for (int j=i+1;j<n&&!flag;j++)
for (int k=0;k<n-1&&!flag;k++)
for (int l=k+1;l<n&&!flag;l++)
if ((i!=k||j!=l)&&(len(node[i],node[j])==len(node[k],node[l])))
{
cout<<"YES"<<endl;
flag=true;
}
if (!flag) cout<<"NO"<<endl;
}
return 0;
}
其实这题就更加气了。我看了别人满分的程序之后,简直就是这个经典【emoji】表情啊!为什么是曼哈顿距离啊!蛇精病啊!我为什么要求直线距离啊!这道题也说明了,要仔细审题。【注:后加说明,M<200,000这也是很重要的一点,做题解的时候再讲
=========================================================
爆裂吧世界(world/1S/64M)
【题目描述】
给你一个长度为n的数列A,请你计算里面有多少个四元组(a,b,c,d)满足:
a≠b≠c≠d,1≤a<b≤n,1≤c<d≤n,Aa<Ab,Ac>Ad
【输入格式】
输入文件第一行有一个整数N,第二行有N个整数A1,A2⋯An
【输出格式】
输出文件仅一行,为一个整数,表示满足条件的四元组的数量
【输入1】
4
2 4 1 3
【输出1】
1
【输入2】
4
1 2 3 4
【输出2】
0
【数据约定】
15% n<=100
100%n<=50000
A在int范围里
#include<iostream>
#include<cstdio>
using namespace std ;
int main()
{
freopen("world.in","r",stdin);
freopen("world.out","w",stdout);
int a[10000];
int n,ans=0;
cin>>n;
for (int i=0;i<n;i++)
cin>>a[i];
for (int i=0;i<n-1;i++)
for (int j=i+1;j<n;j++)
for (int k=0;k<n-1;k++)
for (int l=k+1;l<n;l++)
if (i!=k&&i!=l&&j!=k&&j!=l)
if (a[i]<a[j]&&a[k]>a[l]) ans++;
cout<<ans<<endl;
return 0;
}
没多少时间给我多想了,我一开始就猜到是要用树状数组【看数据就知道是logN】但是没有想到具体怎么做,时间也不够了,就随便交了个暴力的算法,拿了个部分分。