D题Operator Precedence
#include<bits/stdc++.h>
using namespace std;
int main(){
int t;
cin>>t;
while(t--){
int n;
cin>>n;
if(n==3){//n为3时要特判,因为n-3为0
cout<<1<<" "<<-10<<" "<<6<<" "<<6<<" "<<-10<<" "<<1<<endl;
continue;
}
cout<<n*(-1)+3<<" ";
for(int i=1;i<=n-1;i++){
cout<<-1<<" "<<2<<" ";
}
cout<<1<<endl;
}
system("pause");
return 0;
}
M题Mysterious Tree
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int edge(int a,int b){
cout<<"? "<<a<<" "<<b<<endl;
cout<<endl;
int x;
cin>>x;
return x;
}
void solve(){
int n;
cin>>n;
int pos=-1;
for(int i=1;i<=n-1;i+=2){
int x=edge(i,i+1);
if(x==1){//检查每两个之间是否相连(由n/2想到),如果都不相连说明是一个链
pos=i;
break;
}
}
//要特判最后两个值,因为总数可能为奇数
if(pos==-1&& n&1 ){
int x=edge(n-1,n);
if(x==1) pos=n-1;
}
if(pos==-1){
cout<<"! 1"<<endl;
cout<<endl;
return ;
}
if(pos!=1){
//pos为1时情况特殊要排除,可以先考虑不为1时
//不为1时,我们先观察pos这个点能否成链
int x=edge(pos,pos-2);
if(x==1)//如果与pos-2相连,看是否与pos-1相连
{
int y=edge(pos,pos-1);
//如果与pos-1相连,说明一定为星
if(y==1){
cout<<"! 2"<<endl;
cout<<endl;
return ;
}else{
//不相连一定为链,因为这时候pos点已经连接了两个点了
cout<<"! 1"<<endl;
cout<<endl;
return ;
}
}
else{//当pos不于pos-2相连时,我们观察pos+1与pos-2和pos-1的关系
//接下来就与上面相同了
int y=edge(pos+1,pos-2);
if(y==0){
cout<<"! 1"<<endl;
cout<<endl;
return ;
}else{
int z=edge(pos+1,pos-1);
if(z==1){
cout<<"! 2"<<endl;
cout<<endl;
return ;
}else{
cout<<"! 1"<<endl;
cout<<endl;
return ;
}
}
}
}
else{//开始特判当pos为1时
int x=edge(1,3);
if(x==1){
int y=edge(1,4);
if(y==1){
cout<<"! 2"<<endl;
cout<<endl;
return ;
}else{
cout<<"! 1"<<endl;
cout<<endl;
return ;
}
}else{
int y=edge(2,3);
if(y==0){
cout<<"! 1"<<endl;
cout<<endl;
return ;
}else{
int z=edge(2,4);
if(z==1){
cout<<"! 2"<<endl;
cout<<endl;
return ;
}else{
cout<<"! 1"<<endl;
cout<<endl;
return ;
}
}
}
}
}
int main(){
int t;
cin>>t;
while(t--){
solve();
}
return 0;
}
M题V-Diagram
这道题一定要看清题,题中给的就是一个V图,就不用再排序了。然后针对于这个图,我们发现最大的有可能的三个范围实际上就是全部的sum/n或者是最低点左边的全部和加上右边第一个除以对应的个数或者是最低点右边的和加上最低点左边的数除以相应的个数,这个可以大概理解一下,因为如果说中间大,那么一定有两边的数大于中间的数,这时候就会提高平均值,所以最值一定会在端点处出现的,所以我们讨论这三种情况就行。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll a[300030];//注意用long long
int main(){
int t;
cin>>t;
while(t--){
int n;
cin>>n;
ll mi=0x3f3f3f3f;
int cnt=0;
for(int i=1;i<=n;i++){
cin>>a[i];
if(a[i]<mi){
mi=a[i];
cnt=i;
}
}
ll sum=0;//直接开double不可以,因为输入时用int类型,转化为double会TLE
ll sumL=0;
ll sumR=0;
for(int i=1;i<=cnt+1;i++){
sumL+=a[i];
}
for(int i=cnt-1;i<=n;i++){
sumR+=a[i];
}
for(int i=1;i<=n;i++){
sum+=a[i];
}
cout<<fixed<<setprecision(10)<<max(max(1.0L*sumL/(cnt+1),1.0L*sumR/(n-cnt+2)),1.0L*sum/n)<<endl;
}
system("pause");
return 0;
}
这个代码中要注意的是,我们最后要保留9位输出的话,也就是意味着我们要使用double类型的变量,但输入时数据为int类型,这时候如果我们刚开始就把sum等变量设置为dounle类型,我们的每次输入计算机就要转化一次类型,从而导致TLE。因此我们直接用int接受,但最后使用出发求职的时候用1.0L*res这种方式使得结果变为double类型。
目前先讲解这三道题(主要目前就会这三道)吧,咳咳