882 | xilinshancun | 1100 75:59 | 100 1:51 | 200 6:12 | 300 9:40 | - | 500 75:59 |
感觉AT 基本都是数学思维题
A:签到。。
B:枚举每个点做为图形右下角的贡献即可。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define re register
#define ls (o<<1)
#define rs (o<<1|1)
//#define m (l+r)/2
#define pb push_back
typedef pair<int,int> pii;
const double PI= acos(-1.0);
const int M = 1e5+7;
/*
int head[M],cnt=1;
void init(int n){cnt=1;for(int i=0;i<=n;i++)head[i]=0;}
struct EDGE{int to,nxt,w;}ee[M*2];
void add(int x,int y,int w){ee[++cnt].nxt=head[x],ee[cnt].w=w,ee[cnt].to=y,head[x]=cnt;}
*/
char s[110][110];
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
int n,m;
cin>>n>>m;
for(int i=1;i<=n;i++)
cin>>(s[i]+1);
int ans=0;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++){
if(s[i][j]=='#')continue;
if(i>1){
if(s[i-1][j]=='.')ans++;
}
if(j>1&&s[i][j-1]=='.')ans++;
}
cout<<ans<<endl;
return 0;
}
C:简单的set应用
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define re register
#define ls (o<<1)
#define rs (o<<1|1)
//#define m (l+r)/2
#define pb push_back
typedef pair<int,int> pii;
const double PI= acos(-1.0);
const int M = 2e5+7;
/*
int head[M],cnt=1;
void init(int n){cnt=1;for(int i=0;i<=n;i++)head[i]=0;}
struct EDGE{int to,nxt,w;}ee[M*2];
void add(int x,int y,int w){ee[++cnt].nxt=head[x],ee[cnt].w=w,ee[cnt].to=y,head[x]=cnt;}
*/
int a[M];
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
int n;
cin>>n;
set<int>s;
for(int i=0;i<=n;i++)s.insert(i),a[i]=1;
for(int i=1;i<=n;i++){
int x;
cin>>x;
if(a[x]){
s.erase(x);
a[x]=0;
}
cout<<*s.begin()<<endl;
}
return 0;
}
E:枚举每个整洁广场算贡献就行。
对于一个整洁点 (x,y),假设共p个点亮灯可以使得该广场点亮,K个整洁点。
则该广场亮的方案数为: (p个点至少一个点亮,其余点随便)
所有整洁点贡献和就是答案。
所以我们只要求出每个点的p就行。
每行枚举,求出一段连续整洁点,长度为t,然后给这段每个点的p都加上t。
每列同样枚举。
最后每个点会重复加一次,减一即可!
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define re register
#define ls (o<<1)
#define rs (o<<1|1)
//#define m (l+r)/2
#define pb push_back
typedef pair<int,int> pii;
const double PI= acos(-1.0);
const int M = 2e3+7;
/*
int head[M],cnt=1;
void init(int n){cnt=1;for(int i=0;i<=n;i++)head[i]=0;}
struct EDGE{int to,nxt,w;}ee[M*2];
void add(int x,int y,int w){ee[++cnt].nxt=head[x],ee[cnt].w=w,ee[cnt].to=y,head[x]=cnt;}
*/
const int mod = 1e9+7;
int n,m;
ll qpow(ll a,ll b){
ll ans=1;
while(b){
if(b&1)ans=ans*a%mod;
a=a*a%mod;
b/=2;
}
return ans;
}
int nm[M][M];
char s[M][M];
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cin>>n>>m;
// \sum{ 2^{k-x} * 2^{x-1} }.x是每个点可达的点数
for(int i=1;i<=n;i++){
cin>>(s[i]+1);
}
int sm=0;
for(int i=1;i<=n;i++)
{
int tp=0,lst=1;
for(int j=1;j<=m+1;j++){
if(s[i][j]=='.')tp++,sm++;
else{
for(int k=lst;k<j;k++)nm[i][k]+=tp;
lst=j+1;
tp=0;
}
}
}
for(int j=1;j<=m;j++)
{
int tp=0,lst=1;
for(int i=1;i<=n+1;i++){
if(s[i][j]=='.')tp++;
else{
for(int k=lst;k<i;k++)nm[k][j]+=tp;
lst=i+1;
tp=0;
}
}
}
ll ans=0;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++){
if(nm[i][j]==0)continue;
nm[i][j]--;
// cout<<i<<" - "<<j<<" "<<nm[i][j]<<" - "<<ans<<endl;
ans=(ans+(qpow(2,nm[i][j])-1+mod)%mod*qpow(2,sm-nm[i][j])%mod)%mod;
}
cout<<ans<<endl;
return 0;
}
D题感觉挺难做的,我思路是把两个正方形拼成一个矩形,求矩形再正方形中出现次数就好做了,但还没想好就结束了。。等别的大佬的题解吧。。