A题:dfs,从打到搜索
#include<iostream>
#include<math.h>
#include<stdio.h>
#include<algorithm>
#include<string.h>
#include<vector>
#include<queue>
#include<map>
#include<set>
#define B(x) (1<<(x))
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int oo = 0x3f3f3f3f;
const ll OO = 0x3f3f3f3f3f3f3f3f;
const double eps = 1e-9;
#define lson rt<<1
#define rson rt<<1|1
void cmax(int& a, int b){ if (b>a)a = b; }
void cmin(int& a, int b){ if (b<a)a = b; }
void cmax(ll& a, ll b){ if (b>a)a = b; }
void cmin(ll& a, ll b){ if (b<a)a = b; }
void cmax(double& a, double b){ if (a - b < eps) a = b; }
void cmin(double& a, double b){ if (b - a < eps) a = b; }
void add(int& a, int b, int mod){ a = (a + b) % mod; }
void add(ll& a, ll b, ll mod){ a = (a + b) % mod; }
const ll MOD = 1000000007;
const int maxn = 50;
int a[maxn];
ll sum[maxn];
int f;
void dfs(int s, int l){
if (f) return;
if (l > sum[s]) return;
if (l == sum[s] || l == 0){
f = 1;
return;
}
for (int i = s; i >= 1; i--){
if (l >= a[i])
dfs(i - 1, l - a[i]);
}
}
int main(){
int n, m;
while (scanf("%d %d", &n, &m) != EOF){
sum[0] = 0;
for (int i = 1; i <= n; i++){
scanf("%d", &a[i]);
sum[i] = sum[i - 1] + a[i];
}
f = 0;
dfs(n, m);
if (f) printf("Yes\n");
else printf("No\n");
}
return 0;
}
B题:ac自动机,将前后相减等到的串去匹配,由于有负值,所以用结构体,用map存边。
#include<iostream>
#include<math.h>
#include<stdio.h>
#include<algorithm>
#include<string.h>
#include<vector>
#include<queue>
#include<map>
#include<set>
using namespace std;
#define B(x) (1<<(x))
typedef long long ll;
const int oo = 0x3f3f3f3f;
const ll OO = 1LL << 61;
const int MOD = 10007;
const int maxn = 110000;
const int maxm = 1000005;
const int SIZE = 1000005;
int Next_[maxm];
//const int type=4;
inline int gcd(int a, int b)
{
return b == 0 ? a : gcd(b, a%b);
}
struct Node
{
int x;
Node(){}
Node(int a){
x = a;
}
bool operator==(const Node& a)const{
return x == a.x;
}
bool operator!=(const Node& a)const{
return x != a.x;
}
bool operator<(const Node& a)const{
return x < a.x;
}
}a[maxn], b[maxn];
void input(Node buff[], int len){
int x, y;
scanf("%d", &x);
for (int i = 1; i<len; i++){
scanf("%d", &y);
buff[i] = Node(y - x);
x = y;
}
}
map<Node, int>Next[SIZE];
int fail[SIZE], flag[SIZE];
int cnt, root;
int newNode(){
Next[cnt].clear();
flag[cnt++] = 0;
return cnt - 1;
}
void Init(){
cnt = 1;
root = newNode();
}
void Insert(Node buff[], int len){
int now = root;
Node k;
for (int i = 1; i <= len; i++){
k = buff[i];
if (Next[now][k] == 0)
Next[now][k] = newNode();
now = Next[now][k];
}//for
flag[now]++;
}
void build(){
fail[root] = 0;
Node k;
queue<int>Q;
///注:next[now][i] <=> it->second ; i <=>it->first;
for (map<Node, int>::iterator it = Next[root].begin(); it != Next[root].end(); ++it){
fail[it->second] = root;
Q.push(it->second);
}//for
while (!Q.empty()){
int now = Q.front(); Q.pop();
flag[now] += flag[fail[now]];
for (map<Node, int>::iterator it = Next[now].begin(); it != Next[now].end(); ++it){
int temp = fail[now];
int nxt = Next[temp][it->first];
while (temp&&!nxt){
temp = fail[temp];
nxt = Next[temp][it->first];
}
if (temp) fail[it->second] = nxt;
else fail[it->second] = root;
Q.push(it->second);
}//for
}//while
}
ll Search(Node buff[], int len){
int now = root;
ll ans = 0;
for (int i = 1; i <= len; i++){
int nxt = Next[now][buff[i]];
while (now&&!nxt){
now = fail[now];
nxt = Next[now][buff[i]];
}
if (now) now = nxt;
else now = root;
ans += flag[now];
}//for
return ans;
}
void get_next(Node T[], int len)
{
int i = 0;
Next_[i] = -1;
int j = -1;
while (i<len)
{
if (j == -1 || T[i] == T[j]){
i++; j++;
Next_[i] = j;
}
else j = Next_[j];
}
}
ll kmp(Node S[], Node T[], int lenS, int lenT){
ll ans = 0;
int i = 0, j = 0;
while (i<lenS){
if (j == -1 || S[i] == T[j]){
i++;
j++;
}
else j = Next_[j];
if (j == lenT) ans++;
}//for
return ans;
}
int main(){
int T, m, n, k;
ll ans;
while (scanf("%d %d", &n, &m) != EOF){
Init();
input(a, n);
ans = 0;
if (m > 1){
for (int i = 1; i <= m; i++){
scanf("%d", &k);
input(b, k);
if (k > 1) Insert(b, k - 1);
else ans += n;
}
build();
ans += Search(a, n - 1);
}
else{
scanf("%d", &k);
input(b, k);
if (k > 1){
get_next(b + 1, k - 1);
ans = kmp(a + 1, b + 1, n - 1, k - 1);
}
else ans += n;
}
cout << ans << endl;
}
return 0;
}
D题:二分图,先判断二分图,然后二分匹配。
#include<iostream>
#include<math.h>
#include<stdio.h>
#include<algorithm>
#include<string.h>
#include<string>
#include<vector>
#include<queue>
#include<map>
#include<set>
#define B(x) (1<<(x))
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
void cmax(int& a, int b){ if (b>a)a = b; }
void cmin(int& a, int b){ if (b<a)a = b; }
void cmax(ll& a, ll b){ if (b>a)a = b; }
void cmin(ll& a, ll b){ if (b<a)a = b; }
void add(int& a, int b, int mod){ a = (a + b) % mod; }
void add(ll& a, ll b, ll mod){ a = (a + b) % mod; }
#define lson rt<<1
#define rson rt<<1|1
const int oo = 0x3f3f3f3f;
const ll OO = 0x3f3f3f3f3f3f3f3f;
const ll MOD = 1000000007;
const int maxn = 333;
map<string, int> mat;
char s1[20], s2[20];
int g[maxn][maxn], col[maxn];
int mac[maxn], vis[maxn];
int n;
bool jud(){
queue<int>q;
memset(col, -1, sizeof col);
for (int i = 1; i <= n; i++){
if (col[i] != -1)continue;
col[i] = 1;
q.push(i);
while (!q.empty()){
int u = q.front(); q.pop();
for (int v = 1; v <= n; v++)if (g[u][v]){
if (col[v] == -1){
col[v] = 1 - col[u];
q.push(v);
}
else if (col[u] == col[v]) return false;
}
}
}
return true;
}
int dfs(int u){
for (int i = 1; i <= n; i++){
if (g[u][i] && !vis[i]){
vis[i] = 1;
if (mac[i] == -1 || dfs(mac[i])){
mac[i] = u;
return 1;
}
}
}
return 0;
}
int Match(){
memset(mac, -1, sizeof mac);
int ans = 0;
for (int i = 1; i <= n; i++){
memset(vis, 0, sizeof vis);
ans += dfs(i);
}
return ans;
}
int main(){
int m;
while (scanf("%d %d", &n, &m) != EOF){
int cnt = 0;
mat.clear();
memset(g, 0, sizeof g);
for (int i = 1; i <= m; i++){
scanf("%s %s", s1, s2);
if (!mat[s1])mat[s1] = ++cnt;
if (!mat[s2])mat[s2] = ++cnt;
g[mat[s1]][mat[s2]] = 1;
g[mat[s2]][mat[s1]] = 1;
}
if (!jud()) puts("No");
else{
printf("%d\n", Match());
}
}
return 0;
}
E题:
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
using namespace std;
int a[2][2], b[2][2], c[2][2], g[2];
#define exp 1e-6
int main()
{
int n;
while (~scanf("%d", &n))
{
int x, y, z, m;
a[0][0] = a[1][1] = a[1][0] = a[1][1] = 0;
b[0][0] = b[1][1] = b[1][0] = b[1][1] = 0;
c[0][0] = c[1][1] = c[1][0] = c[1][1] = 0;
g[0] = g[1] = 0;
for (int i = 0; i < n; i++)
{
scanf("%d%d%d%d", &x, &y, &z, &m);
a[m][x]++;
b[m][y]++;
c[m][z]++;
g[m]++;
}
scanf("%d%d%d", &x, &y, &z);
double xx, yy;
xx = (a[0][x] + 1.0 / n)*b[0][y] / n*c[0][z] / n*g[0];
yy = (a[1][x] + 1.0 / n)*b[1][y] / n*c[1][z] / n*g[1];
if (yy - xx > exp)
puts("Come on guys,you can do it!");
else
puts("Poor guys,you can go back to sleep now..");
}
}
F题:结论题
G题:TL
H题:ORZ
I:贪心,根据上车的人数从小到大排序,然后从终点站到这往前推,如果出现负值说明这种情况无解。
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
struct node
{
int x, y;
}a[110000];
bool cmp(node a, node b)
{
return a.y < b.y;
}
int main()
{
int n;
while (~scanf("%d", &n))
{
for (int i = 0; i < n; i++)
scanf("%d%d", &a[i].x, &a[i].y);
sort(a, a + n, cmp);
long long sum = 0;
bool flag = true;
if (a[0].y != 0)
puts("No");
else
{
for (int i = 0; i < n; i++)
{
sum -= a[i].y;
if (sum < 0)
{
flag = false;
break;
}
sum += a[i].x;
}
if (flag)
puts("Yes");
else
puts("No");
}
}
}
J题:乱搞
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<math.h>
using namespace std;
int x[1100000], y[1100000];
int main()
{
int n;
while (~scanf("%d", &n))
{
for (int i = 0; i < n; i++)
scanf("%d%d", &x[i], &y[i]);
sort(y, y + n);
int k = y[n / 2];
long long sum = 0;
for (int i = 0; i < n; i++)
sum += abs(y[i] - k);
printf("%lld\n", sum);
}
}