p1:Valera and X
判断矩阵是否形同X,形同X就是对角线上元素相同,,其他位置上的所有元素相同并且不同于对角线上的元素。直接模拟判断...
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
typedef long long ll;
char s[440][440];
int n;
int main()
{
// freopen("in.txt","r",stdin);
scanf("%d",&n);
for (int i=0; i<n; i++)
scanf("%s",s[i]);
bool ok1=true;
bool ok2=true;
for (int i=1; i<n; i++)
{
if (s[i][i]!=s[i-1][i-1]) ok1=false;
}
for (int i=1; i<n; i++)
{
if (s[i][n-i-1]!=s[i-1][n-i]) ok1=false;
}
if (!ok1) puts("NO");
else
{
if (s[0][0]==s[0][1])
{
ok2=false;
}
s[0][0]=s[0][n-1]=s[0][1];
for (int i=1; i<n; i++)
{
s[i][i]=s[i-1][i-1];
}
for (int i=1; i<n; i++)
{
s[i][n-i-1]=s[i-1][n-i];
}
for (int i=0; i<n; i++)
for (int j=0; j<n; j++)
if (s[i][j]!=s[0][0])
{
ok2=false;
break;
}
if (ok2) puts("YES");
else puts("NO");
}
return 0;
}
P2: Marathon
在一个正方形的跑道上逆时针跑步,边长a,给出d,n,对于1...n每一个i,求出跑i*d的距离时,所在位置的坐标(定义左下角是(0,0))。由于给的数保证小数点后不超过4位,所以可以直接乘10W或者100W化成整数来做,那么剩下的问题就是对一个长度,求出在正方形上的位置了,取模后判断一下就行..
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
typedef long long ll;
double a,d;
ll aa,dd,n;
const int fx[4]={1,0,-1,0};
const int fy[4]={0,1,0,-1};
double eps=0.000000001;
void pos(ll len,ll &x, ll &y)
{
len%=(aa*4);
if (len<=aa)
{
x=len;
y=0;
}
else
if (len>aa && len<=aa*2)
{
x=aa;
y=len-aa;
}
else
if (len>aa*2 && len<=aa*3)
{
x=aa-(len-2*aa);
y=aa;
}
else
{
len=4*aa-len;
x=0;
y=len;
}
}
int main()
{
scanf("%lf%lf",&a,&d);
aa=(a+eps)*(1000000.0);
dd=(d+eps)*(1000000.0);
scanf("%d",&n);
ll x=0,y=0;
int dr=0;
double xx,yy;
for (int i=1; i<=n; i++)
{
pos(i*d*1000000,x,y);
xx=x/1000000.0;
yy=y/1000000.0;
printf("%.6lf %.6lf\n",xx,yy);
}
return 0;
}
P3: Restore Graph
给以的数组D[],D[i]表示某个点到i的最短路,给出k,构造出最短路符合要求并且每个点连的边不超过k的原图...
下意识感觉可以插成一棵树,这样的话记录一下每个距离都有哪些节点,控制好每个节点的边数,一层一层的BFS就好,因为是一棵树,所以最后ans一定等于n-1,要么就是无解了..另外注意特判D数组,D数组有且只能有1个0...我只判断了大于1个的情况,结果复测挂在D数组没有0的情况了.....
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <vector>
#include <queue>
using namespace std;
typedef long long ll;
const int maxn=101000;
int n,m,k;
int d[maxn];
vector<int> g[maxn];
vector<int> b[maxn];
int main()
{
// freopen("in.txt","r",stdin);
while(~scanf("%d%d",&n,&k))
{
int st=0;
for (int i=1; i<=n; i++)
{
scanf("%d",&d[i]);
b[d[i]].push_back(i);
if (!d[i]) st=i;
}
bool ok=true;
queue<int> q;
q.push(st);
int cc=1;
int i=0,j=0;
int ans=0;
if (b[0].size()!=1)
{
cout<<"-1"<<endl;
continue;
}
while(!q.empty())
{
while( !q.empty() && d[q.front()]<cc-1) q.pop();
if (q.empty()) break;
int ct=k-1;
int u=q.front();
if (u==st) ct++;
q.pop();
if (d[u]>=cc)
{
ok=false; break;
}
for (i; i<b[cc].size()&&ct; i++,ct--)
{
g[u].push_back(b[cc][i]);
ans++;
q.push(b[cc][i]);
}
if (i==b[cc].size())
{
cc++;
i=0;
}
}
if (!ok || ans<n-1 || b[0].size()>1)
{
cout<<"-1"<<endl;
}
else
if (ans)
{
cout<<ans<<endl;
for (int i=1; i<=n; i++)
for (int j=0; j<g[i].size(); j++)
{
if (i<=g[i][j]) cout<<i<<" "<<g[i][j]<<endl;
else cout<<g[i][j]<<" "<<i<<endl;
}
}
else cout<<"-1"<<endl;
}
return 0;
}
给出一个一维的扫雷状态,求有多少种符合要求的填充方法...
对于0,1,2,*,可以看成4中状态,另外1还要分成1左边有雷和右边有雷两种情况,所以一共就是5种状态了..
0,1,2,3,4分别对应0,1左边有雷,1右边有雷,2,雷,
那么有状态转移方程:
dp[0][i]=dp[0][i-1]+dp[1][i-1];
dp[1][i]=dp[4][i-1];
dp[2][i]=dp[1][i-1]+dp[0][i-1];
dp[3][i]=dp[4][i-1];
dp[4][i]=dp[2][i-1]+dp[3][i-1]+dp[4][i-1];
最后统计一下dp[0][n-1]+dp[1][n-1]+dp[4][n-1]的答案。
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
typedef long long ll;
const int maxn=1100000;
const int mod=1000000007;
ll dp[6][maxn];
int n,m;
char s[maxn];
inline int idx(int p)
{
if (s[p]=='*') return 4;
else if (s[p]=='2') return 3;
else if (s[p]=='0') return 0;
else if (s[p]=='1')
{
if (p==0 || s[p-1]=='*') return 1;
else if (p==n-1 || s[p+1]=='*') return 2;
else return 5;
}
}
int main()
{
// freopen("in.txt","r",stdin);
scanf("%s",s);
n=strlen(s);
memset(dp,0,sizeof dp);
if (s[0]=='?')
{
dp[0][0]=dp[2][0]=dp[4][0]=1;
dp[1][0]=dp[3][0]=0;
}
else
{
if (s[0]=='0') dp[0][0]=1;
else if (s[0]=='1') dp[2][0]=1;
else if (s[0]=='*') dp[4][0]=1;
}
for (int i=1; i<n; i++)
{
if (s[i]=='?')
{
dp[0][i]=dp[0][i-1]+dp[1][i-1];
dp[1][i]=dp[4][i-1];
dp[2][i]=dp[1][i-1]+dp[0][i-1];
dp[3][i]=dp[4][i-1];
dp[4][i]=dp[2][i-1]+dp[3][i-1]+dp[4][i-1];
}
else
{
if (s[i]=='0') dp[0][i]=dp[0][i-1]+dp[1][i-1];
else if (s[i]=='1') dp[1][i]=dp[4][i-1],dp[2][i]=dp[1][i-1]+dp[0][i-1];
else if (s[i]=='2') dp[3][i]=dp[4][i-1];
else if (s[i]=='*') dp[4][i]=dp[2][i-1]+dp[3][i-1]+dp[4][i-1];
}
for (int j=0; j<5; j++)
if (dp[j][i]>mod) dp[j][i]%=mod;
}
ll ans=0;
ans=dp[0][n-1]+dp[1][n-1]+dp[4][n-1];
ans%=mod;
cout<<ans<<endl;
return 0;
}
P5:Maze 1D
题意都还没看懂....来日再补...