总结目录
今天学习了栈,跟vector差不多
相当于没学什么,卡在哪个排序输出栈(优先数组)哪里不知道怎么写
今晚听了一下课,感觉 有点思路了,明天再写,二叉树今天也推掉了
今天就交刷题记录算了
A
无视距离,那就是桶排序了
循环变量1-100000就行了
int 范围也够了
B
说实话,每看到一个题目我就想暴力,,,虽然说这种方法比穷举好了点,,其实也是说明给的提示
找到最左边的坑的区间每个坑填一格
然后超时了,我寻思按说明来做都能超时,(应该除了算法超时是没有逻辑错误的,测试了几次了已经)
#include<iostream>
#include<string>
#include<algorithm>
#include<functional>
#include<string>
#include<string.h>
#define LEN 10000
//10000*1000貌似也不是很大,不会超时
using namespace std;
int a[100010];
int main()
{
int len;//当前区间端点
int sum = 0;//填平道路段数
int n;
cin >> n;
int i, j, k;
for (i = 0; i < n; i++)
{
cin >> a[i];
}
while (1)
{
//for (i = 0; a[i] == 0, i < n; i++);//找左区间
for (i = 0; a[i] == 0&& i < n; i++);
int love = i;
for (; a[i] != 0&& i < n; i++);
int life = i;
if (love == life)
break;
else
{
for (i = love; i < life; i++)
{
a[i]--;
//sum++;
}
sum++;
}
}
cout << sum << endl;
}
然后仔细想了想
while(1)最多是n
里面还有个可以忽略时间的if
和一个最差为n的for
看一下数据
最差情况确实会超时,除非只有1000
查了些资料
也就是说只能写几个并列的for、while……
那这只能取巧了,利用题目特点,只能在一个坑里面施工,施工次数是该坑最深深度
简而言之,碰到坑成立就立即填平!
遍历到4时 构成一个坑1 坑2 先将坑1 填平 再将坑2 填平
接着遍历 碰到5 又构成坑 再将坑3填平
这就只要遍历一次就能将施工次数统计出来
O(n)代码
#include<iostream>
#include<string>
#include<algorithm>
#include<functional>
#include<string>
#include<string.h>
using namespace std;
int a[100010];
int main()
{
int n;
cin>>n;
int sum=0;
for(int i=0;i<n;i++)
{
cin>>a[i];
if(a[i]>a[i-1])
sum+=a[i]-a[i-1];
}
cout<<sum;
}
说是话一开始我也觉得a[-1]会报错,但是c没有越界检查,而且a[-1]的值还刚好是0??
挺奇妙的索性就这样了
C
这应该是个练手题吧
先看看 给一串泡泡 输出结果
第一感觉是动态数组用vector但是
分类讨论,但是不知道为什么用vector做老是有错
下面是用栈来做的
代码
#include<utility>
#include<iostream>
#include<stdio.h>
#include<string>
#include<algorithm>
#include<map>
#include<vector>
#include<stack>
using namespace std;
string a;
int main()
{
while(getline(cin,a))
{
stack <char> STL;
int i=0;
while(a[i]!='\0')
{
//非首次 且相同
if(!STL.empty()&&STL.top()==a[i])
{
STL.pop();
if(a[i]=='o')//oO
{
//小泡泡出栈
//if(!STL.empty()&&STL.top()==a[i]) 没注意这里写错了
if(!STL.empty()&&STL.top()=='O')
{
STL.pop();
}
else
{
STL.push('O');
//最多只有1个大泡泡后终止
}
}
}
else//首次
{
STL.push(a[i]);//直接压栈
}
i++;
}
string temp;
while(!STL.empty())
{
//cout<<STL.top()<<" ";
temp+=STL.top();
STL.pop();
} //顺序反了
for(int j=temp.length()-1; j>=0; j--)
{
cout<<temp[j];
}
cout<<endl;
}
return 0;
}
F
考过的题目
两个变量记录当前瓶盖数和瓶子数 一个计数变量记录总和
终止条件
瓶盖不够换 瓶子不够换
主要是记录初始数据 然后循环写对就行了
顺便翻出了以前的代码
回忆一下
#include<stdio.h>
#include<stdbool.h>
#include<math.h>
int main()
{
int a[10086];
int i=0,n,k;
int N,M;
int b[10000],c;
int t;
int e,j,m;
scanf("%d",&N);
for(i=0;i<N;i++)
{
scanf("%d",&m);
e=m;
j=m;
n=m;
m=0;
while(e>=3||j>=4||m>0)
{
m=e/3+j/4;
n+=m;
e=e%3+m;
j=j%4+m;
}
if(i!=0)
printf("\n");
printf("%d",n);
}
return 0;
}
下面是代码
#include<iostream>
#include<stdio.h>
#include<string>
#include<algorithm>
#include<map>
#include<vector>
#include<stack>
using namespace std;
int main()
{
int i,j, k;
int N, M;
int sum;
int cup, bout, m;
cin >> N;//组数
for (i = 0; i < N; i++)
{
cin >> m;//瓶数
cup = m;
bout = m;
sum = m;
while (cup >= 3 || bout >= 4 )
{
m = cup / 3 + bout / 4;
sum += m;
cup = cup % 3 + m;
bout = bout % 4 + m;
}
if (i != 0)
cout<<endl;
cout<<sum;
}
return 0;
}
G
一开始没想清楚WA了一发
直接就求a,b,c 和3的最小公倍数
实际上 求a,b,c的最小公倍数*3就好了
最小公倍数保证总人数平分
*3保证每组能平分且每人至少一瓶
原始代码点这里
代码
#include<iostream>
#include<stdio.h>
#include<string>
#include<algorithm>
#include<map>
#include<vector>
#include<stack>
using namespace std;
int di_gui(int x,int y)
{
return y==0?x:di_gui(y,x%y);
}
int main()
{
int a,b,c;
cin>>a>>b>>c;
int temp1=di_gui(a,b);
temp1=a*b/temp1;
int temp2=di_gui(temp1,c);
temp2=temp1*c/temp2;
cout<<temp2*3<<endl;
return 0;
}
H
这种题之前没接触过
下面是资料链接
简而言之
奇数分成互质的b,c
偶数就是 (自身/2)平方-1 (自身/2)平方-1+2
#include<iostream>
#include<stdio.h>
#include<string>
#include<algorithm>
#include<map>
#include<vector>
#include<stack>
using namespace std;
string a;
int main()
{
int n;
cin>>n;
long long b,c;
long long t;
t=n/2;
if(n<3 )
{
cout<<"-1";
}
else
{
if(n%2==0)//偶数 这里用 n&1==0居然不对 优先级问题!!
{
b=t*t-1;
c=b+2;
}
else
{
b=t*t*2+2*t;
c=b+1;
}
cout<<b<<" "<<c;
}
return 0;
}