周总结
Vjudge题目总结
题目网址:https://vjudge.net/contest/426531
M.
这个题读懂题意更重要
错误题意1.
错把66为底箱子当成都是666的箱子
错误题意2.
错把箱子为11 22 33…的高度看成与底边边长相等
真●题意:箱子的高度其实可以直接忽略,因为一个箱子里面的高度全都相等,这个题意就是用来挖坑的,坏的很,读懂题意的话,就可以直接转化为平面问题——切木板问题,一个66的木板,切所需数量nn的木板,最少用多少个66的木板,题意读懂,整个题思路的困难就迎刃而解
思路:按照从小到大,依次切木板,求最少需要66木板的数量,66 55 44每一个要切的木板都需要一个66的木板来操作,而33的木板4个需要1个66的木板,这里根据计算机除法运算的规律,用33的数量+3之后除以4,得到33所用的66木板数,然后计算出66木板所剩的22木板的空位,填入22木板后,多了加木板,然后计算所剩1*1可切木板数,少了直接计算数目,最后输出结果
P.
题意:这个题最重要的就是题意部分,看着很长很复杂,可能会写很多代码,其实总结一遍题意,最后可以直接等价为求n个人里面最先到达终点的人所用的时间
思路:一开始没有读透题意,写了一堆代码
while(l<4500)
{
t=(p[j+1].t-p[j].t)*p[j+1].v/(p[j+1].v-p[j].v);
for(i=j+2;i<n;i++)
{
temp_t=(p[i].t-p[j].t)*p[i].v/(p[i].v-p[j].v);
if(temp_t<t)
{t=temp_t;j=i;}
}
if(temp_v*t<4500)
{sum+=t;
l+=temp_v*t;}
else
{
t=(4500-l)/temp_v;
sum+=t;
l=4500;
}
temp_v=p[j].v;
j++;
if(j==n-1)
{sum+=(4500-l)/temp_v;l=4500;}
}//看似逻辑清晰,结果也没错,可就是没AC
其实根本不用这么麻烦,直接求最快到达的时间,然后输出
在AC之后,我发现了一个非常有意思的事情,这个是AC的代码:
#include <iostream>
#include <algorithm>
#include <iomanip>
using namespace std;
struct tim
{
int v,t;
double ti;
}p[10005];
bool cmp(tim a,tim b)
{
return a.ti<b.ti;
}
int main()
{
int n,i,j,sum;
while(cin>>n&&n!=0)
{
for(i=0;i<n;i++)
{
cin>>p[i].v>>p[i].t;
p[i].ti=p[i].t+4.5/p[i].v*3600;
}
sort(p,p+n,cmp);
for(i=0;i<n;i++)
if(p[i].t>=0)
break;
sum=p[i].ti;
if(sum!=p[i].ti)
sum++;
cout<<sum<<endl;
}
return 0;
}
我只修改了一个地方
for(i=0;i<n;i++)
{
cin>>p[i].v>>p[i].t;
p[i].ti=p[i].t+4.5/p[i].v*3600;//修改为 p[i].ti=p[i].t+4500/p[i].v*3.6;或者改为p[i].ti=p[i].t+4500/(p[i].v/3.6);
}
如果进行修改,则是wrong answer这让我感觉有点摸不着头脑,如果站在数学的思路看问题,完全没有错误,但为什么在机器上这三个式子却不成立,为了搞明白怎么回事,我把sum设置为double类型,把代码
if(sum!=p[i].ti)
sum++;
去掉,然后输入同样的例子
2
21 0
22 34
AC的代码p[i].ti=p[i].t+4.5/p[i].v3600;输出的结果是770.364
改为p[i].ti=p[i].t+4500/p[i].v3.6;输出的结果是768.4
改为p[i].ti=p[i].t+4500/(p[i].v/3.6);输出的结果是770.364
显然,第一个修改后连输出结果都出现了错误
但是第二个修改之后结果并没有错误,但提交之后仍然是wrong answer
为什么?
等号左边p[i]ti,这是double类型,p[i].t是int整形
先看AC代码,p[i].ti=p[i].t+4.5/p[i].v3600;根据优先级,先左后右,小数除以整型变量,没有问题,然后小数乘以整数,得小数也没有问题
再看修改的第一个代码,p[i].ti=p[i].t+4500/p[i].v3.6;根据优先级先左后右,第一个修改后先除法4500/p[i].v就出现了错误,整形除整形,如果结果不是整数,那么就会出现精度的缺失,后面整型乘3.6没有问题
再看第二个修改的代码,p[i].ti=p[i].t+4500/(p[i].v/3.6);括号内整数除以小数,括号外仍然是整数除以小数,为了防止巧合,我又写了一段代码
int main()
{
double p;
p=4+28/3.6;
cout<<p;
return 0;
}
结果仍然没有出现精度缺失,那么就只剩下一种情况,就是想AC就不能出现整数除以小数的形式,但是小数可以除以整数
W.
思路:首先这个题应该弄清楚先算最少时间还是先算最少次数,如果像题中说的一样,最少时间的时候的最少次数,可能会先想办法把最少时间求出来,但是这样反倒不好求,如果先求最少次数,然后可以直接顺水推舟求出来最少时间,最少次数即总车数除以一次可以运送的车数,即可得到总共需要的最少次数,如果该除数有余数则先运送余数,并输入最先运送的车到达的时间,现在所用的最少时间即最大时间加2t,然后再输入剩下的车辆到达时间,在输入的汽车数可以装满一整船(即达到n时)进行时间判断,如果时间未达到上次船回到码头的时间,最少时间直接+2t,否则按照到达时间的最大值作为托运开始时间进行托运,运送完最后一批车时,时间减速一个t即得到最少花费时间
这个题其实并不算难,但为什么让很多人望而却步?简单分析一下,就是对于判断模棱两可,不知道判断标准,就像为什么在不能整除时要先运余数而不是后运余数,其实只要一组数据就可以说明
2 10 3
10
40
40
在等待可以满载的时候其实就是在浪费时间
还有就是涉及的变量太多,如果一次性定义所有产量难免会产生一些看不出来的小错误,解决办法就是在需要变量时再进行定义,同时在循环结束时也减少了变量值的重置
#include <iostream>
using namespace std;
int main()
{
int k;
cin>>k;
int n,t,m;
while(k--)
{
cin>>n>>t>>m;
int a=m%n;
int times=m/n;
if(a!=0)
times++;
int minTime=0,ship,i=0;
if(a)
{
for(i=0;i<a;i++)
cin>>ship;
minTime=ship+2*t;
}
int ans=0;
while(i<m)
{
cin>>ship;
ans++;
if(ans==n)
{
if(ship>minTime)
minTime=ship+2*t;
else minTime+=2*t;
ans=0;
}
i++;
}
minTime-=t;
cout<<minTime<<" "<<times<<endl;
}
return 0;
}
课上题目:
直线上有n个城市, 第i个城市和i+1个城市是相邻的. 每个城市都有vi的金币.
Alice和Bob站在城市p, 他们每天可以选择走向一个相邻的城市, 也可以选择不走. 他们是单独行动的.
他们经过一个城市就可以获得相应的金币(不能重复获得)
作为一个队伍, 他们的最远距离不能超过M, 问T天内, 他们最多一共能拿多少金币?
思路:其实如果T一直大于M/2的话,这个题就非常简单,同时相对而行,直到距离达到M,所用天数为d,然后在接下来T-d天内哪里金币多往哪里走,如果天数到了,还没有达到M,直接所有城市的金币相加啊,更简单,所以不需要判断语句,但是要判断M的奇偶性,偶数很简单,主要是奇数,仔细一想奇数也很好判断,但是需要的if判断语句好像有点多,在M较大时,需要判断需要哪边走的天数为偶数,然后再判断再往哪边走可以得到最大值,我感觉直接列举,因为奇数也只有四种情况,得到四种情况的最大值,输出。
3.25CF
题目A
A题目其实非常非常简单,就像是初中水平数学的一道益智题,或者是高中数学里面一道5分的选择或者填空题,但是为什么花费了这么长时间,还出现了这么多次错误?
1:没有做到简化题目,对题目理解不够,对题目分析不到位,就像高中老师常给我们说的一句话:“你要明白出题人的目的,出题人想考察你什么”,我在看到题目的时候第一个想到的不是找规律,而是去定义二维数组使用for循环。
2:受贪心思想和Vjudge上题目的影响,不会想到这一题直接两个加减乘除的式子就可以解决,最后还是在敲代码的时候发现,二维数组根本用不到,用for循环做出来之后提交发现超时,这才想到用一个if语句和两个加减乘除的式子解决该问题
题目B
当时太着急了,以至于心急没吃到热豆腐
思路还是有的,不过当时没写出来:
在输入字符的时候进行判断,在p[i]==星号 时记录i的位置,到最后的位置记录就是最后一个符号的位置,并令其等于’.’,然后使用for循环,记录下temp=第一个的位置同样使其等于’.’,同时数量+1使用for循环,如果i-temp<=3&&p[i]==星号 跳过,否则的话temp=当前位置,然后p[temp]=’.’,变换的数量+1;
最后输出
感想:
还是感觉老毛病,思路还没清晰,就开始敲代码,浪费时间浪费心态,应该好好改一下,最近贪心算法的题做的差不多了,初识了动态规划,感觉更难了,感觉到了不小的压力,不过想想还是坚持下去吧,就像养成习惯一样,最开始是因为好奇心驱使或者一时兴起,慢慢的兴趣不再像开始那样,坚持下去也非常困难,但是如果度过了这个困难期,最后的成为了习惯,生活中失去他就变得非常困难了