第二次比赛部分题解
-
P7060 [NWRRC2014] Alarm Clock
#include <bits/stdc++.h>
using namespace std;
int main() {
int n;
cin>>n;
int arr[10]={6,2,5,5,4,5,6,3,7,6};
bool check= false;
//对于时间ab:cd
for(int a=0;a<=2;a++){ //a最多可以到2(因为最大为23小时)
for(int b=0;b<10;b++){ //b0到9都有可能(10:00到19:00)
for(int c=0;c<=5;c++){//分钟最多到59,所以c位最大位5
for(int d=0;d<10;d++){//最后一位0-9都有可能
if(arr[a]+arr[b]+arr[c]+arr[d]==n){ //遍历所有,第一个满足的输出
cout<<a<<b<<":"<<c<<d;
check= true; //如果输出了答案,那么就不输出impossible
break; //只能跳出当前循环,因此需要多个break
}
}
if(check) break;
}
if(check)break;
}
if(check) break;
}
if(!check) cout<<"Impossible"; //如果没有符合条件的,那么输出impossible
return 0;
}
-
P1451 求细胞数量
#include <bits/stdc++.h>
using namespace std;
int n,m;
int cell[105][105]; //记录细胞
bool vis[105][105]; //标记位置
int ans=0;
int main() {
cin>>n>>m;
for(int i=0;i<n;i++){
string str; //输入的数字没有空格隔开,不能用int型来存,否则一行会被认为是一个数字。
cin>>str; //读入当前行字符串
for(int j=0;j<m;j++){
cell[i][j]=str[j]-'0'; //读入字符串之后再把每个数字拆开,存放到int数组中(char数组也行)
}
}
queue< pair<int,int> > que; //队列中每个元素都是pair,每个元素都存放两个int数据.
for(int i=0;i<n;i++){ //从头开始遍历cell
for(int j=0;j<m;j++){
if(vis[i][j]==1||cell[i][j]==0) continue; //如果当前的cell被标记过,或者当前的cell不是细胞,直接进行下一次循环
if(vis[i][j]==0&&cell[i][j]!=0){ //如果当前位置的cell是细胞,而且没有被标记过,那么入列
que.emplace(i,j); //这里是位置入列,因为我们需要从这个位置,延申到上下左右的位置。如果是把cell存放的数字入列,则不能找到该cell上下左右是否还是cell
ans++; //答案加一 因为和这个位置有关的细胞,都被视为一个细胞
}
while(que.size()){ //如果队列里面还有细胞(不为0的数据)的话,就一直延申,一直查找,一直标记这个被视为一个细胞的细胞。直到0把这个细胞都分割开,不再有数据能入列,那么这个细胞的
pair<int,int> top;
top=que.front(); //把队首存放的坐标(cell的坐标)取出,存放到top;
que.pop();//把队首出列
//下列的4个if就是判断现在这个这个细胞(不为0的元素)的上下左右方向是否是细胞,是否没有被标记过
if( top.first+1<n && cell[top.first+1][top.second]!=0 && vis[top.first+1][top.second]==0){ //首先判断这个方向的位置是否在范围之内,然后判断是否数据为0,是否被标记过
que.emplace(top.first+1,top.second);//如果这个细胞(不为0的数据)在范围之内,而且数据不为0,而且没有被标记过,那么这个细胞的位置要入列,需要通过这个细胞的位置延申下去
vis[top.first+1][top.second]=1;//入列之后标记,避免重复延申
}
if( top.first-1>=0 && cell[top.first-1][top.second]!=0 && vis[top.first-1][top.second]==0){
que.emplace(top.first-1,top.second);
vis[top.first-1][top.second]=1;
}
if( top.second-1>=0 && cell[top.first][top.second-1]!=0 && vis[top.first][top.second-1]==0){
que.emplace(top.first,top.second-1);
vis[top.first][top.second-1]=1;
}
if( top.second+1<m && cell[top.first][top.second+1]!=0 && vis[top.first][top.second+1]==0){
que.emplace(top.first,top.second+1);
vis[top.first][top.second+1]=1;
}
}//当这个while循环结束,意味着这个细胞已经延申完了,最外层的循环接着遍历这个cell里面的数据,查看是否还有没有被标记的不为0的数据
}
}
cout<<ans;
return 0;
}
-
[ABC043B] バイナリハックイージー
#include <bits/stdc++.h>
using namespace std;
int main() {
string str;
cin>>str;
int len=str.length();
stack<char> stk; //栈:先进后出
for(int i=0;i<len;i++){
if(str[i]!='B'){ //如果遇到0或者1,入栈
stk.emplace(str[i]);
}
else{ //否则如果是B
if(!stk.empty()){ //如果此时栈里有数据,弹出
stk.pop();
}
}
}
vector<char> vct; //因为栈是先进后出,直接一个一个输出里面元素的话是倒着的,所以要把栈里的元素倒过来
while (stk.size()){ //当栈不是空的时候(size!=0)
vct.emplace_back(stk.top());
stk.pop();
}
for(int i=vct.size()-1;i>=0;i--){ //从vet的后面往前面输出
cout<<vct[i];
}
return 0;
}
-
P8829 [传智杯 #3 练习赛] 单位转换
#include <bits/stdc++.h>
using namespace std;
int main() {
string str;
cin>>str;
double num=0;
int situation;
int len=str.length();
//一个没有技术含量的代码。。
for(int i=0;i<len;i++){ //从前往后遍历,遇到第一个字母就判断situation为哪种种情况,按不同情况进行不同计算方式
if(str[i]=='M'){
num=stoi(str.substr(0,i+1)); //把该字母之前的数字字符串截取出来( 函数substr() ),再把截取出来的纯字符串转化为数字(函数stoi())
situation=1;
break;
}//以下同理
if(str[i]=='G'){
num=stoi(str.substr(0,i+1));
situation=2;
break;
}
if(str[i]=='K'){
num=stoi(str.substr(0,i+1));
situation=3;
break;
}
if(str[i]=='B'){
num=stoi(str.substr(0,i+1));
situation=4;
break;
}
}
if(situation==1){ //如果是情况1:即式子左边单位是MB ,转化为不同单位时进行不同的运算 //因为输入格式是固定的,字符串倒数第二个字符一定是'M','G','K' else是情况‘k’
if(str[len-2]=='M'){
cout<<fixed<<setprecision(6)<<num; //如果左边单位和右边单位一样,那么直接输出原数据
}
else if(str[len-2]=='G'){
cout<<fixed<<setprecision(6)<<num/pow(2,10);
}
else if(str[len-2]=='K'){
cout<<fixed<<setprecision(6)<<num*pow(2,10);
}
else{
cout<<fixed<<setprecision(6)<<num*pow(2,20);
}
}
//以下同理
if(situation==2){
if(str[len-2]=='M'){
cout<<fixed<<setprecision(6)<<num*pow(2,10);
}
else if(str[len-2]=='G'){
cout<<fixed<<setprecision(6)<<num;
}
else if(str[len-2]=='K'){
cout<<fixed<<setprecision(6)<<num*pow(2,20);
}
else{
cout<<fixed<<setprecision(6)<<num*pow(2,30);
}
}
if(situation==3){
if(str[len-2]=='M'){
cout<<fixed<<setprecision(6)<<num/pow(2,10);
}
else if(str[len-2]=='G'){
cout<<fixed<<setprecision(6)<<num/pow(2,20);
}
else if(str[len-2]=='K'){
cout<<fixed<<setprecision(6)<<num;
}
else{
cout<<fixed<<setprecision(6)<<num*pow(2,10);
}
}
if(situation==4){
if(str[len-2]=='M'){
cout<<fixed<<setprecision(6)<<num/pow(2,20);
}
else if(str[len-2]=='G'){
cout<<fixed<<setprecision(6)<<num/pow(2,30);
}
else if(str[len-2]=='K'){
cout<<fixed<<setprecision(6)<<num/pow(2,10);
}
else{
cout<<fixed<<setprecision(6)<<num;
}
}
return 0;
}
-
P2985 [USACO10FEB] Chocolate Eating S
#include <bits/stdc++.h>
using namespace std;
int n,d; //n为巧克力数,d为要吃的天数
int ccl[50005]; //存放巧克力
bool check(long long x){ //x=mid
long long happy=0; //第一天开心值为0
int j=0; //j记录吃了多少巧克力
for(int i=1;i<=d;i++){ //从第一天开始
if(happy!=0) happy= floor(happy/2); //每天新开始都会happy减半
while (happy<x){ //每一天都要满足最大不开心值x(即mid) 如果不够开心,那么就吃巧克力,直到happy>=x,吃一块j++一次
if(j<n) happy+=ccl[j];
j++;
if(j>n) return false; //如果吃完了巧克力,happy值还是不够,那么这个x(mid) 是不满足条件的,返回 false;
}
}
return true;
}
int main() {
ios::sync_with_stdio(false),cin.tie(nullptr),cout.tie(nullptr);
cin>>n>>d;
for(int i=0;i<n;i++){
cin>>ccl[i];
}
long long l=1;
long long r=1e18; //边界一定要够大,否则wa
long long mid;
long long ans=LONG_LONG_MIN; //初始化
while(l<=r){ //二分答案
mid=l+(r-l)/2;
if(check(mid)){ //如果最小happy值mid,可以满足,那么mid应该往右边走,尝试找更大的答案
l=mid+1;
ans=max(ans,mid);//记录最大的!!,满足条件的(能进这个if条件的都是满足的)!!,答案;
}
else r=mid-1;
}
cout<<ans<<"\n"; //把找到满足条件的最不开心那天最大的happy值输出
long long happy=0;
int j=0;
for(int i=1;i<=d;i++){ //把check函数修改一下,已经找到的ans答案是怎么吃的,把每天是怎么吃的 输出
if(happy!=0) happy= floor(happy/2);
while (happy<ans){
if(j<n) happy+=ccl[j];
j++;
cout<<i<<"\n"; //输出吃这块巧克力时候的天数
}
}
int k=n-j; //这一步是关键!!! 如果历经d天之后,通过吃巧克力维持happy值,同时满足最大不开心那天ans,有可能到了最后一天,还有没有吃完的巧克力
//,这个时候就要把剩下的巧克力在最后一天吃了
while(k--){ //没吃完的最后一天吃,最后剩下几个就输出几个最后一天
cout<<d<<"\n";
}
return 0;
}