A题
求三元组满足QAQ且三元组中的xyz不相邻。
模拟即可。每次找到一个a,答案为左边Q的数量乘以右边Q的数量。
注意longlong
#include
using namespace std;
#define ll long long
#define up(i,a,n) for(int i=a;i<=n;i++)
const int maxn=5e3+10;
int arr[maxn];
int main()
{
string s;
cin>>s;
ll ans=0;
if(s.size()<3)
{
return 0*printf("0\n");
}
int end=s.size()-1;
if(s[0]=='Q')arr[0]=1;
for(int i=1;i<s.size();i++)
{
arr[i]=arr[i-1]+(s[i]=='Q');
}
for(int i=2;i<s.size()-2;i++)
{
if(s[i]=='A')
{
ans+=arr[i-2]*(arr[end]-arr[i+1]);
}
}
printf("%lld\n",ans);
}
B题
暴力模拟
连成线一共就那么几种方法,横着三种,竖着三种,对角线两个。
每一次按照题目的意思去模拟对比就行了。写的略嫌麻烦。
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
//#include
#include
#define up(i,a,b) for(int i=a;i
#define dw(i,a,b) for(int i=a;i>b;i--)
#define upd(i,a,b) for(int i=a;i<=b;i++)
#define dwd(i,a,b) for(int i=a;i>=b;i--)
//#define local
typedef long long ll;
const double esp = 1e-6;
const double pi = acos(-1.0);
const int INF = 0x3f3f3f3f;
const int inf = 1e9;
using namespace std;
int read()
{
char ch = getchar(); int x = 0, f = 1;
while (ch<'0' || ch>'9') { if (ch == '-')f = -1; ch = getchar(); }
while (ch >= '0' && ch <= '9') { x = x * 10 + ch - '0'; ch = getchar(); }
return x * f;
}
typedef pair<int, int> pir;
char grp[5][5];
int t;
bool judge()
{
int ans1 = 0;
int ans2 = 0;
int ans3 = 0;
up(i, 0, 3)
{
if (grp[i][0] == 'W')ans1++;
if (grp[i][1] == 'W')ans2++;
if (grp[i][2] == 'W')ans3++;
}
if (ans1 == 3||ans2==3||ans3==3)return true;
ans1 = 0; ans2 = 0; ans3 = 0;
up(i, 0, 3)
{
if (grp[0][i] == 'W')ans1++;
if (grp[1][i] == 'W' )ans2++;
if (grp[2][i] == 'W')ans3++;
}
if (ans1 == 3 || ans2 == 3 || ans3 == 3)return true;
ans1 = 0; ans2 = 0; ans3 = 0;
int temp = 0;
int temp2 = 2;
up(i, 0, 3)
{
if (grp[i][temp++] == 'W' )ans1++;
if (grp[i][temp2--] == 'W')ans2++;
}
if (ans1 == 3 || ans2 == 3)return true;
return false;
}
int main()
{
t = read();
while (t--)
{
int temp = 0;
up(i, 0, 3)
{
scanf("%s", grp[i]);
}
bool flag = false;
bool flag2=false;
bool flag3 = false;
up(i, 0, 3)
{
up(j, 0, 3)
{
if (grp[i][j] == '#') {
grp[i][j] = 'W';
if (judge())flag = true;
grp[i][j] = '#';
}
}
}
if (!flag) { cout << "Bob" << endl; continue; }
up(i, 0, 3)
{
up(j, 0, 3)
{
if (grp[i][j] == 'W') {
grp[i][j] = 'B';
flag3 = false;
up(i, 0, 3)
{
up(j, 0, 3)
{
if (grp[i][j] == '#')
{
grp[i][j] = 'W';
if (judge())flag3 = true;
grp[i][j] = '#';
}
}
}
if (!flag3)flag2 = true;
grp[i][j] = 'W';
}
}
}
if (!flag2)cout << "Alice" << endl;
else cout << "Emmm" << endl;
}
return 0;
}
C题 比上一题简单。
简单构造。
#include
using namespace std;
#define ll long long
#define up(i,a,n) for(int i=a;i<=n;i++)
int main()
{
int n;
scanf("%d",&n);
if(n==1)
{
return 0*printf("0");
}
if(n%2==1)return 0*printf("-1");
int mid=n/2,m=n-1,y=n-2;
up(i,1,mid)
{
printf("%d ",m);
m-=2;
}
printf("0 ");
up(i,1,mid-1)
{
printf("%d ",y);
y-=2;
}
return 0;
}
D题。对于位操作的题目。data structure是在骗人
这里or表示锁零,ans表示锁1。
我们借此就可以每一次贪心的去分出m个区间来。
每一次如果没有变的话就沿用上一次的答案。
#include
using namespace std;
#define ll long long
#define up(i,a,n) for(int i=a;i<=n;i++)
int main()
{
int n;
scanf("%d",&n);
if(n==1)
{
return 0*printf("0");
}
if(n%2==1)return 0*printf("-1");
int mid=n/2,m=n-1,y=n-2;
up(i,1,mid)
{
printf("%d ",m);
m-=2;
}
printf("0 ");
up(i,1,mid-1)
{
printf("%d ",y);
y-=2;
}
return 0;
}
E题不会。
F题。最大闭合权。
感觉没有啥好说的。就是抄模板就行了
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
//#include
#include
#define up(i,a,b) for(int i=a;i
#define dw(i,a,b) for(int i=a;i>b;i--)
#define upd(i,a,b) for(int i=a;i<=b;i++)
#define dwd(i,a,b) for(int i=a;i>=b;i--)
//#define local
typedef long long ll;
const double esp = 1e-6;
const double pi = acos(-1.0);
const int INF = 0x3f3f3f3f;
const int inf = 1e9;
using namespace std;
int read()
{
char ch = getchar(); int x = 0, f = 1;
while (ch<'0' || ch>'9') { if (ch == '-')f = -1; ch = getchar(); }
while (ch >= '0' && ch <= '9') { x = x * 10 + ch - '0'; ch = getchar(); }
return x * f;
}
typedef pair<int, int> pir;
int n, m;
const int N = 1e4;
struct edge { int to, cap, rev; };
vector<edge>grp[N];
int iter[N], level[N];
void addedge(int from, int to, int cap)
{
grp[from].push_back(edge{ to,cap,(int)grp[to].size() });
grp[to].push_back(edge{ from,0,(int)grp[from].size() - 1 });
}
void bfs(int s)
{
queue<int >que;
memset(level, -1, sizeof(level));
que.push(s);
level[s] = 0;
while (!que.empty())
{
int temp = que.front();
que.pop();
up(i, 0, grp[temp].size())
{
edge &e = grp[temp][i];
if (e.cap > 0 && level[e.to] < 0)
{
level[e.to] = level[temp] + 1;
que.push(e.to);
// cout << "*" << endl;
}
}
}
}
int dfs(int s, int t, int f)
{
if (s == t)return f;
for (int &i = iter[s]; i < grp[s].size(); i++)
{
edge &e = grp[s][i];
if (e.cap > 0 && level[e.to] > level[s])
{
int d = dfs(e.to, t, min(f, e.cap));
if (d > 0)
{
e.cap -= d;
grp[e.to][e.rev].cap += d;
return d;
}
}
}
return 0;
}
int min_flow(int s, int t, int f)
{
int res = 0;
int d = 0;
while (1)
{
bfs(s);
//cout << "*";
if (level[t] < 0)return res;
memset(iter, 0, sizeof(iter));
while ((d = dfs(s, t, f)) > 0)
{
//cout << d << endl;
res += d;
}
}
}
int getln(int x,int y)
{
return (x-1)*n + y;
}
int main()
{
n = read();
m = read();
int x = 0;
int S = 0;
int T = n * n + 2 * n + m + 1;
int ans = 0;
upd(i, 1, n)
{
upd(j, 1, n)
{
x = read();
addedge(S, getln(i, j) + 2 * n, x);
addedge(getln(i, j) + 2 * n, i, INF);
addedge(getln(i, j) + 2 * n, j + n, INF);
ans += x;
}
}
upd(i, 1, n)
{
x = read();
addedge(i, T, x);
}
upd(i, 1, n)
{
x = read();
addedge(i + n, T, x);
}
int s1, t1, s2, t2, k;
upd(i, 1, m)
{
s1 = read(), t1 = read(), s2 = read(), t2 = read(), k = read();
addedge(S, 2 * n + n * n + i, k);
addedge(2 * n + n * n + i, getln(s1, t1) + 2 * n, INF);
addedge(2 * n + n * n + i, getln(s2, t2) + 2 * n, INF);
ans += k;
}
//cout << ans << endl;
cout << ans - min_flow(S, T, INF)<<endl;
return 0;
}