浪在ACM集训队寒假集训第二场补题
本来是想写博客来 但是网页码字以及有些方面还是不习惯 那就写在笔记里吧
//电脑端右上角演示功能我挺喜欢的。(这好像是我第一次认真补题~~~)
题目还没补完 准确的说是还没读完 读英文题对我简直是种折磨
大意:n个气球,k个小朋友,然后再输入n个气球的颜色,如果某个颜色的气球大于小朋友个数,那气球就有剩余,输出NO否则输出YES
AC代码:
#include <bits/stdc++.h>
using namespace std;
int n,k,num[1000];//定义为全局变量 所以就自动初始化为零
int main(){
string a;
cin>>n>>k;
cin>>a;
for(int i=0;i<n;i++)
num[a[i]]++; //num[气球颜色的ASCII码]
for(int i=0;i<1000;i++)//
{
if(num[i]>k)//再枚举一遍如果气球个数大于小朋友个数
{
cout<<"NO\n";
return 0;
}
}
cout<<"YES\n";
return 0;
}
大意:n个数里面 有奇数第一个就赢 否则第二个赢 找到这个规律这个题就简单了
一定要关闭流同步 否则会超时!!!
AC代码:
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
long long n,a[1000005];
int main(){
ios::sync_with_stdio(0);//一定要关闭流同步 否则会超时
cin.tie(0);
cout.tie(0);
cin>>n;
for(int i=0;i<n;i++)
cin>>a[i];
for(int i=0;i<n;i++)
{
if(a[i]&1)
{
puts("First");
return 0;
}
}
puts("Second");
return 0;
}
- C题url:https://vjudge.net/problem/CodeForces-841C
- D题url:https://vjudge.net/problem/CodeForces-841D
- E题url:https://vjudge.net/problem/CodeForces-611D
大意:判断2016年中有多少个周几 ,或者有多少个多少号,需要注意点是2016有43个周五和周六,其余的42个。2016是闰年,二月有29天
AC代码:
#include <bits/stdc++.h>
using namespace std;
int x;
char a[10],b[10];
int main(){
cin>>x>>a>>b;
//cout<<a<<endl;
if(b[0]=='w'){ //判断是week还是mouth
if(x==5||x==6)cout<<53<<endl;
else cout<<52<<endl;
}
else{ //如果是mouth
if(x==30)cout<<11<<endl;
else if(x==31)cout<<7<<endl;
else cout<<12<<endl;
}
return 0;
}
大意:刚看到题的时候,第一感觉就是暴力枚举,毕竟我最爱的还是暴力啊,提交一次后就会发现会Tle,赛后看别人的题解,发现用到的是二维前缀和
a图:
最大的矩形前缀和就等于蓝的矩阵加上绿的矩阵,再减去重叠面积,最后加上小方块,即
sum[i][j] = sum[i][j - 1] + sum[i - 1][j] - sum[i - 1][j - 1] + a[i][j]
引自https://www.cnblogs.com/mrclr/p/8423136.html
b图:
求红色方块面积 就是s1-s2-s3+s4
需要注意的是头文件用#include<bits/stdc++.h>的话,y1会冲突,y1是在math.h里的
#include<iostream>
using namespace std;
char a[510][510];
int x[510][510],y[510][510],m,n,q,x1,x2,y1,y2,ans;
int main()
{
cin>>n>>m;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
cin>>a[i][j];
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
{
if(a[i][j]=='.')
{
if(a[i-1][j]=='.')x[i][j]++;
if(a[i][j-1]=='.')y[i][j]++;
}
x[i][j]+=x[i-1][j]+x[i][j-1]-x[i-1][j-1];//前缀和的重要公式 看a图
y[i][j]+=y[i-1][j]+y[i][j-1]-y[i-1][j-1];//前缀和的重要公式 看a图
}
cin>>q;
while(q--)
{
ans=0;
cin >> x1 >> y1 >> x2 >> y2;
ans+= x[x2][y2] - x[x1][y2] - x[x2][y1 - 1] + x[x1][y1-1];//看b图
ans+= y[x2][y2] - y[x2][y1] - y[x1 - 1][y2] + y[x1-1][y1];//看b图
cout << ans << endl;
}
return 0;
}
这里再贴上mhr大佬的,比我的更简洁,并且更容易懂
mhr大佬博客:https://www.cnblogs.com/baccano-acmer/
/*
* @Date: 2019-01-03 18:48:53
* @URL:
* @LastEditors: YiJieShuSheng
* @LastEditTime: 2019-01-21 10:44:27
*/
#include <iostream>
using namespace std;
int dp[505][505];
char mp[505][505];
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int n,m;
cin>>n>>m;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
{
cin>>mp[i][j];
}
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
{
if(mp[i][j]=='.')
{
if(mp[i][j-1]=='.')
dp[i][j]++;
if(mp[i-1][j]=='.')
dp[i][j]++;
}
dp[i][j]+=dp[i-1][j]+dp[i][j-1]-dp[i-1][j-1];
}
// for(int i=1;i<=n;i++)
// {
// for(int j=1;j<=m;j++)
// cout<<dp[i][j]<<" ";
// cout<<"\n";
// }
int q;
cin>>q;
while(q--)
{
int x1,y1,x2,y2,haha;//定义一个haha 为该减去的
haha=0;//初始化
cin>>x1>>y1>>x2>>y2;
for(int i=x1;i<=x2;i++)
if(mp[i][y1]==mp[i][y1-1]&&mp[i][y1]=='.')haha++;//减去横向相同的 就是我和你说的那种情况
for(int j=y1;j<=y2;j++)
if(mp[x1][j]==mp[x1-1][j]&&mp[x1][j]=='.')haha++;//竖向相同的
cout<<dp[x2][y2]-dp[x2][y1-1]-dp[x1-1][y2]+dp[x1-1][y1-1]-haha<<"\n";
}
}
大意:a到b中所有的整数的二进制中零的个数是1的 例:110,101,11110,10111,11101,,,
再贴个图
AC代码:
#include <bits/stdc++.h>
using namespace std;
long long num=0,a,b;
void dfs(long long x,int y)//y代表x的二进制中有几个零
{
// cout<<"x:"<<x<<"\n";
if(x>b)return;//如果超出范围,就返回
else if(x>=a&&y==1)//如果在范围里 并且只有一个零 那个数就加一
{
num++;
}
if(y==0)dfs(x<<1,1);
//如果是二进制里没有零的话(例:1111111),那么左移一位,最后一位就是零了
//所以就直接dfs左移,然后y是1
dfs((x<<1)+1,y);
//除了零在最后还有 零在中间的
//所以在上边基础上再加一 (例:10,左移一位加一:101)
}
int main(){
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin>>a>>b;
dfs(1,0);
cout<<num<<endl;
return 0;
}