构造C的歪
好水的题,先算出来a,b的差,然后让a,b的最大值加上那个差就可以了
#include<bits/stdc++.h>
using namespace std;
#define int long long
int a,b;
signed main()
{
cin>>a>>b;
int cha=abs(a-b);
cout<<max(a,b)+cha;
return 0;
}
不要三句号的歪
两种方法,第一种是c快速秒
void solve(){
i64 a,b,c;
scanf("%lld,%lld,...,%lld",&a,&b,&c);
cout<<c-b-1;
}
另一种就是全都看成字符串,然后去求第一个逗号和第二个逗号之间的数和第二个逗号之后的数,然后作差
#include<bits/stdc++.h>
using namespace std;
#define int long long
string s;
signed main()
{
cin>>s;
int flag1,flag2,flag3;
for(int i=0;i<s.size();i++)
{
if(s[i]==',')
{
flag1=i;
break;
}
}
for(int i=flag1+1;i<s.size();i++)
{
if(s[i]==',')
{
flag2=i;
break;
}
}
for(int i=s.size()-1;i>=0;i--)
{
if(s[i]==',')
{
flag3=i;
break;
}
}
int ans1=0;
int ans2=0;
int flag=1;
for(int i=flag2-1;i>=flag1+1;i--)
{
ans1+=flag*(s[i]-'0');
flag*=10;
}
flag=1;
for(int i=s.size()-1;i>=flag3+1;i--)
{
ans2+=flag*(s[i]-'0');
flag*=10;
}
cout<<ans2-ans1-1;
return 0;
}
仰望水面的歪
思路:纯思维,我们可以将向量转变成矢量的形式,因为经过折射,
所以在z轴的运动距离应当为h+h-z
在x轴运动的距离为x
在y轴运动的距离为y
所以矢量为(x,y,2*h-c)然后将gcd(x,y,2*h-c)消去即可
#include<bits/stdc++.h>
using namespace std;
#define int long long
int n,h;
int x,y,z;
int gcd(int a,int b)
{
if(b==0)
{
return a;
}
return gcd(b,a%b);
}
signed main()
{
cin>>n>>h;
for(int i=1;i<=n;i++)
{
cin>>x>>y>>z;
int c=h+h-z;
if(gcd(gcd(x,y),c)==1)
{
cout<<x<<" "<<y<<" "<<c<<"\n";
}
else
{
cout<<x/gcd(gcd(x,y),c)<<" "<<y/gcd(gcd(x,y),c)<<" "<<c/gcd(gcd(x,y),c)<<"\n";
}
}
return 0;
}
小心火烛的歪
思路:这题一看数据范围最大就是7就知道是一个暴力模拟题了,因此我们可以用状压去处理,哪一种燃放计划可用,但是我们要从0为开始存储,所以0位表示当前位,也就是去第一个燃放计划是否要进行,也就是从0,遍历到2^(q)-1即可
ps:要判断有没有一种可能全部都被放了杂物,没有燃放烟花的机会,所以直接输出0种即可
#include <bits/stdc++.h>
using namespace std;
#define int long long
int n, m, q;
int a[10][10]; // 堆放杂物是1,没有杂物是0
int b[10][10][10]; // 第k个燃放计划
int c[10][10];
string s;
vector<int> vec;
int minn = LLONG_MAX;
void solve(int x) {
memset(c, 0, sizeof(c));
int cnt = 0;
for (int k = 0; k < q; k++) {
if (x & (1 << k)) {
cnt++;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
if (a[i][j] == 0 && b[i][j][k + 1] == 1) {
c[i][j]++;
} else if (a[i][j] == 1 && b[i][j][k + 1] == 1) {
return;
}
}
}
}
}
int flag = 1;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
if (a[i][j] == 0 && c[i][j] == 0) {
flag = 0;
break;
}
}
}
if (flag&&minn>cnt) {
minn = cnt;
vec.clear();
for (int k = 0; k < q; k++)
{
if (x & (1 << k))
vec.push_back(k+1);
}
}
}
signed main() {
cin >> n >> m >> q;
for (int i = 1; i <= n; i++) {
cin >> s;
for (int j = 1; j <= m; j++) {
a[i][j] = s[j - 1] - '0';
}
}
for (int k = 1; k <= q; k++) {
for (int i = 1; i <= n; i++) {
cin >> s;
for (int j = 1; j <= m; j++) {
b[i][j][k] = s[j - 1] - '0';
}
}
}
for (int i = 0; i < (1 << q); i++) {
solve(i);
}
if (minn == LLONG_MAX) {
cout << -1<<"\n";
} else {
cout << minn<<"\n";
}
for(int i:vec){
cout<<i<<" ";
}
return 0;
}
喜欢切数组的红
这题一开始看走眼了,我以为只需要去让数组划分成三个相等的部分(我记得在cf上做过一个相似的,我说这个我熟啊)然后就错了一部分,没想到竟然是因为每个划分中都要有一个正数
因此我们可以用一个额外的辅助数组,去判断前两个部分的不同划分和以及后两个之间的不同划分,只有为正数的时候才去统计辅助数组,负数直接去继承,即可摆脱负数的困扰
#include<bits/stdc++.h>
using namespace std;
#define int long long
int n;
int a[200005];
int pre[200005];//前缀和数组
int cnt[200005];//到i这个位置,前面出现了多少次sum/3这个大小的次数
int num=0;
int ans=0;
signed main()
{
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>a[i];
pre[i]=pre[i-1]+a[i];
}
int sum=pre[n];
if(sum%3!=0)
{
cout<<0<<"\n";
}
else
{
for(int i=1;i<=n;i++)
{
if(a[i]>0)
{
cnt[i]=num;
}
else
{
cnt[i]=cnt[i-1];
}
if(pre[i]==sum/3)
{
num++;
}
else if(pre[i]==(sum/3)*2)
{
ans+=cnt[i];
}
}
cout<<ans<<"\n";
}
return 0;
}