小明种苹果续
几分钟码完的代码交上去50分百思不得其解,终于还是搜了一下博客才知道有很多“英雄所见略同”的博客qwq
D统计的是发生落果的树的数目,写程序时一旦发生落果就D++,同一棵树可能多次落果,但是这样写D会统计多了,最后改成根据drop数组重新统计了D
这个教训就是,虽然把一些操作放在同一个循环中进行能提高效率,但是也很容易出一些隐蔽的错误,因此在时间复杂度要求不是很严格的情况下还是分开几个循环写不容易出错。
·
·
·
·
·
小明放学
分析出应该用longlong存储才行了,但是define的时候把 #define int long long 错写成#define long long int了,导致一度60分。当然最好以后都直接longlong开。
#include <iostream>
using namespace std;
#define int long long
signed main() {
int r,y,g;
cin >> r >> y >> g;
int n;
cin >> n;
//灯变化红 绿 黄
//数字 1 3 2
int res=0;
for(int i=0;i<n;i++){
int k,t;
cin >> k >> t;
if(k==0){
res+=t;
}else if(k==1){//红灯
int pass=res%(r+y+g);
if(pass<t) res+=(t-pass);
else if(pass>=t && pass<t+g)//原来pass<=t+g,改不改都对,因此题目应该没考察这么特殊的边缘情况,但是严格来讲不该取等
res+=0;
else res+=(r+y+g+t-pass);
}else if(k==2){
//遇到黄灯
int pass = res%(r+y+g);
if(pass<t+r)//剩余黄灯+红灯
res+=(t+r-pass);
else if(pass>=t+r && pass <t+r+g)//<=改成<
res+=0;
else res+=(y+r)-(pass-(t+r+g));
}else if(k==3){
//遇到绿灯
int pass = res%(r+y+g);
if(pass<t)//剩余ts 把等号移到后面
res+=0;
else if(pass>=t && pass <=t+y+r)
res+=t+y+r-pass;
}
}
cout << res;
return 0;
}
·
·
·
·
·
·
买菜
对于区间[1,5],设置1234为true这种,即1为true表示1-2可以闲聊,这样比较两者true重合的个数就好,此思路更简单。(main函数)
如果区间 [1,5],设置12345都为true,统计的时候需要减1,同时如果发生 [1,5], [6,7],那么1-7都为true了,但是5到6是不能算进去的,需要特殊处理更为麻烦,也能做出来。(main1函数)
#include <iostream>
using namespace std;
bool H[1000001]={false};
//main1处理的是都是开区间 所以还要涉及-1的问题 假如说处理为前闭后开区间,即[1,2]只是1为true ,1为true表示12
int main(){
int n;
cin >> n;
for(int i=1;i<=n;i++){
int a,b;
cin >> a >> b;
for(int f=a;f<b;f++)
H[f]=true;
}
int res=0;
for(int i=1;i<=n;i++){
int c,d;
cin >> c >> d;
for(int j=c;j<d;j++){
if(H[j]) res++;
}
}
cout << res;
}
int main1() {
int n;
cin >> n;
for(int i=1;i<=n;i++){
int a,b;
cin >> a >> b;
for(int f=a;f<=b;f++)
H[f]=a;
}
int res=0;
for(int i=1;i<=n;i++){
int c,d;
cin >> c >> d;
int tmp=0;
int flag=-1;
for(int j=c;j<=d;j++){
if(H[j]>0){
if(flag==-1){
tmp++;
flag=H[j];
}else if(H[j]==flag){
tmp++;
}else{
res+=tmp-1;
tmp=1;
flag=H[j];
}
}else{
if(tmp>0){
res+=tmp-1;
tmp=0;
flag=-1;
}
}
}
if(tmp>0){
res+=tmp-1;
}
}
cout << res;
return 0;
}
火车购票:此题没坑,就是想记录一下代码:
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
bool seats[101]= {false};
int main()
{
int n;
cin >> n;
for(int i=0; i<n; i++)
{
int t;
cin >> t;
bool flag=false;
for(int row=1; row<=96; row+=5)
{
for(int col=row; col<=row+5-t; col++)
{
bool f=true;
for(int k=col; k<col+t; k++){
if(seats[k]==true){
f=false;
break;
}
}
if(f==true){
flag=true;
for(int p=col;p<col+t;p++){
seats[p]=true;
cout << p << " ";
}
break;
}
}
if(flag==true) break;
}
if(!flag){
for(int i=1;i<=100;i++){
if(seats[i]==false){
seats[i]=true;
cout << i << " ";
}
}
}
cout << endl;
}
return 0;
}
公共钥匙盒
其实这个题也不难,对借阅时间和归还时间排序依次处理即可,一开始只得了30分,仔细审题发现题目要求同时归还时按照钥匙编号小的归还,cmp的时候只注意让同一时刻归还在先了,所以遇到这种情况,一般都是审题出的问题,耐心读一遍题,考虑一下是不是漏了什么条件~
Z字形扫描
耐心debug就会一点点发现问题在哪的~
#include <iostream>
using namespace std;
int arr[501][501];
int dx[2]= {1,-1};
int dy[2]= {-1,1};
bool isLegal(int x,int y,int n)
{
if(x>=1 && x<=2*n-1 && y>=1 && y<=2*n-1)//2*n-1 X 2*n-1范围内都是合法的,但只有n*n范围内才会输出
return true;
else
return false;
}
bool isCnt(int x,int y,int n){
if(x>=1 && x<=n && y>=1 && y<=n)
return true;
else return false;
}
int main()
{
int n;
cin >> n;
for(int i=1; i<=n; i++)
{
for(int j=1; j<=n; j++)
{
cin >> arr[i][j];
}
}
for(int i=1; i<=2*n-1; i++)//为了能扫描到(n,n)位置,需要右上角/左上角的位置到2*n-1
{
int x,y;
if(i&1)
{
//奇数从(i,1)开始向右上方扫描
x=i;
y=1;
}
else
{
//偶数从(1,i)开始向左下方扫描
x=1;
y=i;
}
while(isLegal(x,y,n))
{
if(isCnt(x,y,n))
{
cout << arr[x][y] << " ";
}
x+=dx[i&1];
y+=dy[i&1];
}
}
return 0;
}