A - Weekly Records
思路:
每求7次累加,输出更新。
代码:
#include<bits/stdc++.h>
using namespace std;
const int N = 100010,mod = 1e6+7;
typedef long long ll;
typedef pair<int,int> pii;
int n,m,k;
int main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
cin >> n;
ll sum = 0;
for(int i = 1;i <= n * 7; i ++ )
{
ll x;
cin >> x;
sum += x;
if(i % 7 == 0)
{
cout << sum << ' ';
sum = 0;
}
}
return 0;
}
B - racecar
思路:
暴力合并即可,检查是否是回文串。时间复杂度(n^2)。
代码:
#include<bits/stdc++.h>
using namespace std;
const int N = 100010,mod = 1e6+7;
typedef long long ll;
typedef pair<int,int> pii;
int n,m,k;
string s[110];
int main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
cin >> n;
for(int i = 1;i <= n; i ++ ) cin >> s[i];
for(int i = 1;i <= n; i ++ )
for(int j = 1;j <= n; j ++ )
{
if(i == j) continue;
string s1, s2;
s1 = s[i] + s[j];
s2 = s1;
reverse(s2.begin(), s2.end());
if(s1 == s2)
{
cout << "Yes\n";
return 0;
}
}
cout << "No\n";
return 0;
}
C - Ideal Sheet
题目描述:就是两个图能否行成一个要求的图,格子有黑和透明的,操作就是将两个图分别覆盖在一个无穷大的二维平面上,只能平移的覆盖,不能剪切和翻转,能够相互覆盖,如果一个格子被黑的覆盖一定显示黑,有黑色的格子不得裁掉,两个图只能使用一次。
思路:
比赛的时候没怎么看懂题,以为这两个图a,b至少使用一次。两个图分别使用一次,就可以分别固定左上角的位置进行暴力枚举,O(10^4)。可以使用一个覆盖后的图与要求的图进行比较即可。一个注意的点,由于图放的位置可能导致黑格可能出界,那么我们可以开个35*35的图进行放置,a图能放的固定左上端点的位置(1~hc+10,1~hc+10),b图能放的固定左上端点的位置同a图一样。
代码:
#include<bits/stdc++.h>
using namespace std;
const int N = 100010,mod = 1e6+7;
typedef long long ll;
typedef pair<int,int> pii;
int ha,hb,hc,wa,wb,wc;
int a[15][15], b[15][15], c[35][35];
int ans[35][35];
char s[15];
int main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
cin >> ha >> wa;
for(int i = 1;i <= ha; i ++ )
{
cin >> (s + 1);
for(int j = 1;j <= wa; j ++ )
a[i][j] = (s[j] == '#');
}
cin >> hb >> wb;
for(int i = 1;i <= hb; i ++ )
{
cin >> (s + 1);
for(int j = 1;j <= wb; j ++ )
b[i][j] = (s[j] == '#');
}
cin >> hc >> wc;
for(int i = 1;i <= hc; i ++ )
{
cin >> (s + 1);
for(int j = 1;j <= wc; j ++ )
c[i + 10][j + 10] = (s[j] == '#'); //将目标图放在中间的位置,防止合成图出界
}
for(int i = 1;i <= hc + 10; i ++ )
for(int j = 1;j <= wc + 10; j ++ )
for(int k = 1;k <= hc + 10; k ++ )
for(int l = 1;l <= wc + 10; l ++ )
{
memset(ans, 0, sizeof ans);
//a图覆盖 (i,j)为a图最左上端点放的位置
for(int p = 1;p <= ha; p ++ )
for(int q = 1;q <= wa; q ++ )
if(a[p][q]) ans[i + p - 1][j + q - 1] = 1;
//b图覆盖 (k,l)为b图最左上端点放的位置
for(int p = 1;p <= hb; p ++ )
for(int q = 1;q <= wb; q ++ )
if(b[p][q]) ans[k + p - 1][l + q - 1] = 1;
int f = 1;
for(int p = 1;p <= 30; p ++ )
for(int q = 1;q <= 30; q ++ )
if(ans[p][q] != c[p][q]) f = 0;
if(f)
{
cout << "Yes\n";
return 0;
}
}
cout << "No\n";
return 0;
}
D - Mismatched Parentheses
思路:
一个括号匹配问题,用栈去维护,如果栈中有(,并且当时访问到的是)那么,就将最近的(及右边的所有东西出栈。
代码:
#include<bits/stdc++.h>
using namespace std;
const int N = 100010,mod = 1e6+7;
typedef long long ll;
typedef pair<int,int> pii;
int n,m,k;
int main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
cin >> n;
string s;
cin >> s;
stack<char> st;
int cnt = 0;
for(int i = 0;i < s.size(); i ++ )
{
char ch = s[i];
if(ch == ')' && cnt)
{
while(st.top() != '(') st.pop();
st.pop();
cnt--;
}
else
{
st.push(ch);
if(ch == '(') cnt++;
}
}
string ans;
while(!st.empty())
{
ans += st.top();
st.pop();
}
reverse(ans.begin(), ans.end());
cout << ans << '\n';
return 0;
}
E - Distinct Adjacent
思路:
当时看完题目感觉有点像当初圆环类涂色问题,n为人的个数,m为人可以拿的数。
,证明的话,我不太确定这样有没有问题,还是写一些。
首先第一个人可以用m种数,接下来的人都拿m-1种数,方法数,第一个人和第n个人可能拿到相同的,需要去重,将1和n颜色相同时合并看作一个人,此时变成n-1个人m种颜色且两两相近的颜色不同的方案数,写出数列关系式
进行递推
不怎么会用latex,请见谅。
代码:
#include<bits/stdc++.h>
using namespace std;
const int N = 100010,mod = 998244353;
typedef long long ll;
typedef pair<int,int> pii;
int n,m,k;
int main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
cin >> n >> m;
ll ans = 0;
if(n & 1) ans = -(m - 1);
else ans = m - 1;
ll t = m - 1;
for(int i = 1;i < n; i ++ )
{
t = (t * (m - 1)) % mod;
}
ans = (ans + t + mod) % mod;
cout << ans << '\n';
return 0;
}