题目链接:https://codeforces.com/contest/1105
C. Ayoub and Lost Array
题目大意:一个长度为n的数组,数组的元素都在[L,R]之间,并且数组全部元素的和可以被3整除,问有多少种方法构建出该数组。答案模1000000007
例
2 1 3
3 note:满足的情况只有[1,2],[2,1],[3,3]
解题思路:用dp[i][j]表示长度为i的数组,元素大小在[L,R]之间,并且元素和模3的余数为j的方案数,我们可以计算出[L,R]范围内模3余0\1\2的数的个数,分别设为num0,num1,num2, 我们可以很容易知道dp[1][0]=num0,dp[1][1]=num1,dp[1][2]=num2,而dp[2][0]需要分情况,当前1个数和模3余0时,第2个数便只能放模3余0的数,即有dp[1][0]*num0种;当前1个数和模3余1时,第2个数便只能放模3余2的数,即有dp[1][1]*num2种;当前1个数和模3余2时,第2个数便只能放模3余1的数,即有dp[1][2]*num1种。dp[n][0]即为我们要求的答案。
于是我们便可以得出递推式:
dp[i][0]=((dp[i-1][0]*num0%mod+dp[i-1][1]*num2%mod)%mod+dp[i-1][2]*num1%mod)%mod;
dp[i][1]=((dp[i-1][0]*num1%mod+dp[i-1][1]*num0%mod)%mod+dp[i-1][2]*num2%mod)%mod;
dp[i][2]=((dp[i-1][0]*num2%mod+dp[i-1][1]*num1%mod)%mod+dp[i-1][2]*num0%mod)%mod;
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<string>
#include<set>
#include<cmath>
#include<list>
#include<deque>
#include<cstdlib>
#include<bitset>
#include<stack>
#include<map>
#include<queue>
using namespace std;
typedef long long ll;
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define pushup() tree[rt]=tree[rt<<1]+tree[rt<<1|1]
const int INF=0x3f3f3f3f;
const double PI=acos(-1.0);
const double eps=1e-;
const ll mod=1e9+;
const int maxn=;
ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
ll lcm(ll a,ll b){return a/gcd(a,b)*b;}
ll dp[][];
ll n,l,r;
int main()
{
ios::sync_with_stdio(false); cin.tie();
cin>>n>>l>>r;
ll num0=r/-(l-)/;
ll num1=num0;
ll num2=num0;
int i,j;
for(i=l;i<=r;i++)
{
if(i%==)break;
else if(i%==)num1++;
else num2++;
}
for(j=r;j>=i;j--)
{
if(j%==)break;
else if(j%==)
{
num2--; break;
}
else if(j%==)
{
num1--; num2--;
break;
}
}
dp[][]=num0; dp[][]=num1; dp[][]=num2;
for(int i=;i<=n;i++)
{
dp[i][]=((dp[i-][]*num0%mod+dp[i-][]*num2%mod)%mod+dp[i-][]*num1%mod)%mod;
dp[i][]=((dp[i-][]*num1%mod+dp[i-][]*num0%mod)%mod+dp[i-][]*num2%mod)%mod;
dp[i][]=((dp[i-][]*num2%mod+dp[i-][]*num1%mod)%mod+dp[i-][]*num0%mod)%mod;
}
cout<<dp[n][]<<endl;
return ;
}
D. Kilani and the Game
题目大意:给出一个n*m的地图,最多9个人,每个人至少含有一个城堡,同时有每个人的扩张速度,即可以连续扩张的次数,现在从1-n轮流从各自的城堡开始扩张,不可通过障碍,求整个地图被扩张完成后,各个人所占领城堡的数目。
Examples
input
3 3 2
1 1
1..
...
..2
output
6 3
解题思路:开始就是想bfs嵌套,先把每一个玩家从1-n的城堡压入第一个队列,再每次把第一个队列的第一个元素弹出,压入第二个队列继续进行bfs,,一直不知道哪里错了,看了别人博客后才发现那样是错的,如果那样做的话,对于这个样例是过不了的:
2 1
1..
1..
..2
...
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<string>
#include<set>
#include<cmath>
#include<list>
#include<deque>
#include<cstdlib>
#include<bitset>
#include<stack>
#include<map>
#include<queue>
using namespace std;
typedef long long ll;
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define pushup() tree[rt]=tree[rt<<1]+tree[rt<<1|1]
const int INF=0x3f3f3f3f;
const double PI=acos(-1.0);
const double eps=1e-;
const ll mod=1e9+;
const int maxn=;
ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
ll lcm(ll a,ll b){return a/gcd(a,b)*b;}
const int dir[][]={{,},{-,},{,},{,-}};
struct node{
int x,y,id;
node(int a,int b,int c):x(a),y(b),id(c){}
};
struct node1{
int x,y,id,steps;
node1(int a,int b,int c,int d):x(a),y(b),id(c),steps(d){}
};
int n,m,sump,s[];
vector<node> p[];
char mp[][];
queue<node> que;
queue<node1> que1;
void BFS()
{
while(que.size())
{
node tmp=que.front();
int id=tmp.id;
que1.push(node1(tmp.x,tmp.y,tmp.id,));
while(que.size()&&que.front().id==id) //判断第一个队列元素是否为当前压入队列是同一个玩家
{
que1.push(node1(que.front().x,que.front().y,que.front().id,));
que.pop();
}
while(que1.size())
{
node1 now=que1.front();
que1.pop();
if(now.steps==s[now.id]){
que.push(node(now.x,now.y,now.id)); //走到最后一步继续压入第一个队列
continue;
}
for(int i=;i<;i++){
int dx=now.x+dir[i][];
int dy=now.y+dir[i][];
if(dx>=&&dx<n&&dy>=&&dy<m&&mp[dx][dy]=='.'){
mp[dx][dy]=''+now.id;
que1.push(node1(dx,dy,now.id,now.steps+));
}
}
}
}
}
int main()
{
ios::sync_with_stdio(false); cin.tie();
cin>>n>>m>>sump;
for(int i=;i<=sump;i++) cin>>s[i];
for(int i=;i<n;i++){
for(int j=;j<m;j++){
cin>>mp[i][j];
if(mp[i][j]>=''&&mp[i][j]<='')
p[mp[i][j]-''].push_back(node(i,j,mp[i][j]-'')); //同一个玩家的城堡压入同一个向量里
}
}
for(int i=;i<=sump;i++)
for(int j=;j<p[i].size();j++)
que.push(p[i][j]);
BFS();
int ans[];
memset(ans,,sizeof(ans));
for(int i=;i<n;i++)
for(int j=;j<m;j++)
for(int k=;k<=sump;k++)
if(mp[i][j]==(k+''))
ans[k]++;
cout<<ans[];
for(int i=;i<=sump;i++)
cout<<" "<<ans[i];
cout<<endl;
return ;
}