A - Vasya's Calendar
CodeForces - 182B
题意:计算调整钟表显示正确的日期的次数,这里只要求显示每月中的日即可。
题解:月份刚好和钟表的一样不用调整,不然就调整差值次数
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include<stack>
#define INF 0x3f3f3f3f
#define lowbit(x) (x&(-x))
using namespace std;
typedef long long LL;
const int MAXN = 2e3 + 10;
const int MOD = 1e9 + 7;
int a[MAXN];
int main()
{
int d;
cin >> d;
int n;
cin >> n;
for(int i = 0; i < n; i++)
cin >> a[i];
int ans = 0;
for(int i = 1; i < n; i++)
{
if(a[i - 1] == d)
continue;
else
ans += (d - a[i - 1]);
}
cout << ans << endl;
}
B - Common Divisors
CodeForces - 182D
题意:求两个字符串的因数个数,同一个子串重复几次后可以得到另一个字符串称为这个子串是另一个字符串的因数
题解:跑kmp的最小循环节之后判断有几个
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include<stack>
#define INF 0x3f3f3f3f
#define lowbit(x) (x&(-x))
using namespace std;
typedef long long LL;
const int MAXN = 2e5 + 10;
const int MOD = 1e9 + 7;
char a[MAXN],b[MAXN];
int na[MAXN],nb[MAXN];
int la,lb;
int main()
{
memset(na,0,sizeof na);
memset(nb,0,sizeof nb);
scanf("%s %s",a,b);
la = strlen(a);
lb = strlen(b);
for(int i = 1; i < la; i++)
{
int j = na[i];
while(j > 0 && a[i] != a[j])
j = na[j];
if(a[i] == a[j])
na[i + 1] = j + 1;
}
for(int i = 1; i < lb; i++)
{
int j = nb[i];
while(j > 0 && b[i] != b[j])
j = nb[j];
if(b[i] == b[j])
nb[i + 1] = j + 1;
}
// for(int i = 0; i < la+5; i++)
// printf("%d ",na[i]);
// cout<<endl;
int lsona = la - na[la];
int lsonb = lb - nb[lb];
if(lsona == 0 || la % lsona)
lsona = la;
if(lsonb == 0 || lb % lsonb)
lsonb = lb;
//printf("%d %d\n",lsona,lsonb);
if(lsona != lsonb)
puts("0");
else
{
int flag = 0;
for(int i = 0; i < lsona; i++) {
if (a[i] != b[i]) {
flag = 1;
}
}
int ans = 0;
int l = lsona;
while(l <= la && l <= lb)
{
if(la % l == 0 && lb % l == 0)
ans++;
l += lsona;
}
if(flag)
puts("0");
else
cout << ans << endl;
}
}
C - Wooden Fence
CodeForces - 182E
题意:有一块地要围上篱笆,现在有m种篱笆,要求用这些篱笆围成长度为 l 的围墙,相邻两个篱笆不能是同一种,并且后一块篱笆的长度应为前一块篱笆的宽度,求最后能围成长为 l 的方案数
题解:dp,将每一个篱笆倒着放置后重新加入dp数组中,dp[M][N] 表示长度为M且为第N种篱笆时的方案数,接下来跑dp保证不是同一个类型的两块篱笆就可以了
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include<stack>
#define INF 0x3f3f3f3f
#define lowbit(x) (x&(-x))
using namespace std;
typedef long long LL;
const int MAXN = 2e2 + 10;
const int MOD = 1e9 + 7;
int m,n;
int a[MAXN],b[MAXN];
LL dp[3500][MAXN];
int main()
{
cin >> m >> n;
memset(dp,0,sizeof dp);
for(int i = 0; i < m; i++)
{
scanf("%d %d",&a[i],&b[i]);
dp[a[i]][i] ++;
if(a[i] != b[i])
{
a[i + m] = b[i];
b[i + m] = a[i];
dp[a[i + m]][i + m]++;
}
}
for(int i = 1;i <= n; i++)
{
for(int j = 0; j < 2 * m; j++)
{
if(!dp[i][j])
continue;
for(int k = 0; k < 2 * m; k++)
{
if (j % m != k % m && a[k] == b[j])
dp[i + a[k]][k] = (dp[i + a[k]][k] + dp[i][j]) % MOD;
}
}
}
LL ans = 0;
for(int i = 0; i < 2 * m; i++)
ans = (ans + dp[n][i]) % MOD;
printf("%lld\n",ans);
}
D - Headquarters
CodeForces - 183A
题意:一些走法,问可以走到的点数有多少
题解:走几步后会形成一个倾斜的矩形,点数就是矩形的面积
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include<stack>
#define INF 0x3f3f3f3f
#define lowbit(x) (x&(-x))
using namespace std;
typedef long long LL;
const int MAXN = 2e2 + 10;
const int MOD = 1e9 + 7;
int a[10];
int main()
{
int n;
cin >> n;
string s;
while(n--)
{
cin >> s;
if(s == "UR")
a[1] ++;
else if (s == "UL")
a[2]++;
else if (s == "DR")
a[4]++;
else if (s == "DL")
a[3]++;
else if (s == "ULDR")
a[0]++;
}
LL len1 = 1 + a[1] + a[3] + a[0];
LL len2 = 1 + a[2] + a[4] + a[0];
cout << len1 * len2 << endl;
}
E - Lemmings
CodeForces - 163B