L,M,M没想到,L暴力过了签到题数据太小了
#include
using namespace std;
long long T,n,m[2][9],ans,mm[10],a[10][9];
int main() {
ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
//样例数
cin>>T;
while (T--)
{
//
long long temp;
//输入数字
cin>>temp;
//预处理
//按余数分类
m[0][temp%9]++;
//temp%10记录的是该数的个位数,temp%9记录的是该数除以9后的余数
a[temp%10][temp%9]++;
//余数为temp%9,在大于10的数中才可能同时存在4和9
if (temp%4==0&&temp>10)
{
//能整除4的数按余数分类
m[1][temp%9]++;
}else if(temp<10){
//记录个位数
mm[temp]++;
}
}
//m[1][0]表示本身就带36,m[0][0]放前面m[1][0]放后面但
//由于不能重复m[1][0]本身属于m[0][0],所以要减1.
ans+=m[1][0]*(m[0][0]-1);
for (int i = 1; i < 9; i++)
{
//m[1]肯定都是自带4的,m[1][i]相当于给第二位数的首位加i,
//m[0][9-i]相当于余了一个9-i,它们两加和为9肯定是能被9整除的
ans+=m[1][i]*(m[0][9-i]);
}
for (int i = 0; i < 10; i++)
{
for (int j = 0; j < 10; j++)
{
//mm记录的是单个数字,a记录的是各位数为i,除以9后余数为9-j的数
//首先不管个位数为i的数字有多大,它都可以表示成num*10+i,后面拼接j
//后可以表示为num*100+i*10+j,num*100显然是可以除以4的,i*10+j如果能除以
//4那就说明整个数都可以除以4,否则如果不是4的倍数那么整体便不能够除以4
//又(9-j)*10+j=90-9j可以整除9所以拼接数字既可以整除4又可以整除9.
if ((10*i+j)%4==0)
{
//个数相乘
ans+=a[i][9-j]*mm[j];
}
}
}
cout<
B题这个博弈我也想了好久
思路如下,如果全为奇数或者全为偶数,qcjj先手,如果数字为奇数个,必定是qcjj胜,要注意最后一个数字不管是奇数还是偶数都可以取,取到最后一个的胜。
如果是奇偶相间,那就分组记录11112222111221,为了方便我把奇数都用1表示,偶数都用2表示,要注意尾相接,我们可以把首尾的1拿出来看11111,可以取4次最后剩下1,12相邻就不能取了,对于2也是一样的2222可以取3次剩一个2,那么怎么做就显而易见了,看可以取几次,奇数次qcjj胜,偶数次zn胜。
using i64 = long long;
using ll = long long;
void solve() {
ll n,a=0,b=0,x=0;
std::cin >>n;
std::vectorc(n);
for (int i = 0; i < n; i++) {
std::cin >> c[i];
//这里很重要&1可以得到他是奇数还是偶数,给定的数字不一定是0或者1,而&1可以把它们同化
if (i&&(c[i]&1) == (c[i - 1]&1)) {
x++;
}
if (c[i] & 1)a++;
else b++;
}
//特判首尾
if((c[0]&1)==(c[n-1]&1))x++;
//特判全为奇数全为偶数
if (a == 0 || b == 0) {
if (a == 0) {
if (b & 1)std::cout << "qcjj" << '\n';
else std::cout << "zn" << '\n';
}
else {
if (a & 1)std::cout << "qcjj" << '\n';
else std::cout << "zn" << '\n';
}
}
else {
if (x & 1)std::cout << "qcjj" << '\n';
else std::cout << "zn" << '\n';
}
}
int main() {
std::ios::sync_with_stdio(false), std::cin.tie(0), std::cout.tie(0);
int t;
std::cin >> t;
while (t--) {
solve();
}
return 0;
}
D也是暴力过的,如果没有交换其实就是一道贪心
using i64 = long long;
using ll = long long;
int main() {
std::ios::sync_with_stdio(false), std::cin.tie(0), std::cout.tie(0);
ll n, k,c=-1e9-5;
std::cin >> n >> k;
std::vectora(n+1),b(n+1);
for (int i = 1; i <= n; i++) {
std::cin >> a[i];
c = std::max(c, a[i]);
b[i] = b[i - 1] + a[i];
}
ll ans = -1E9;
if (k == 0) {
ll suf = -1E9;
for (int i = 1; i <= n; i++) {
suf = std::max(suf, 0LL) + a[i];
ans = std::max(ans, suf);
}
}
else {
for (int i = 1; i < n; i++) {
std::swap(a[i], a[i + 1]);
ll suf = -1E9;
for (int i = 1; i <= n; i++) {
suf = std::max(suf, 0LL) + a[i];
ans = std::max(ans, suf);
}
std::swap(a[i], a[i + 1]);
}
}
std::cout << ans << '\n';
return 0;
}
套个贪心模版就行了。如果只交换一次,那就先交换嘛,交换完贪心然后在交换回来。
G,H合着是个枚举的题。
x,y,z数量少,只要枚举所有情况下的a[1],a[2],a[3],判断给出的所有x,y,z中是否共同满足这一组样例,只要存在就不矛盾。
using namespace std;
typedef long long ll;
int i, j, k, n, m, t, a[4];
vector > v;
bool fun() {
for (auto it = v.begin(); it != v.end();it++) {
//w==1且要a[x]严格小于a[y]
int x = get<0>(*it);
int y = get<1>(*it);
int w = get<2>(*it);
if (w == 1) {
if (a[x] < a[y])continue;
else return 0;
}
else {
//w==0要a[x]>=a[y];
if (a[x] >= a[y])continue;
else return 0;
}
}
return 1;
}
int main() {
ios::sync_with_stdio(0); cin.tie(0);
cin >> t;
while (t--) {
cin >> n;
//创建一个三元组
v = {};
//输入
while (n--) {
cin >> i >> j >> k;
v.push_back({ i,j,k });
}
int res = 0;
//枚举所有情况,如果给定的条件符合其中的一种就是yes,
//毕竟不清楚a[1],a[2],a[3]的分布。
for (i = 1; i <= 3; i++)
for (j = 1; j <= 3; j++)
for (k = 1; k <= 3; k++) {
a[1] = i; a[2] = j; a[3] = k;
res |= fun();
}
if (res)cout << "Yes\n";
else cout << "No\n";
}
}