(*欢迎来到福州*)
Day·1
一波神奇操作,被虐成DOG……………………不过没事被虐是正常的
Problem·1
题面
给出n个点在任意位置插入一个点插入需要时间T1,查找一遍需要时间T2,求最短查出正确点的最大值。
思路
看到最短时间最大,好吧,我想到的是二分答案………………我就的应该可以吧,不过写不出,然后的话,这题正解是一个动规每隔&%%……&&()*个进行插入,这个的话我也不知道怎么搞出来。
题解
代码
#include <iostream>
#include <vector>
#include <algorithm>
#include <cstdio>
using namespace std;
#define rep(i,a,b) for(__typeof(b) i=a; i<(b); ++i)
typedef long long ll;
typedef vector<ll> vl;
int main()
{
freopen("debugging.in", "r", stdin);
freopen("debugging.out", "w", stdout);
int n, t, c;
scanf("%d %d %d", &n, &t, &c);
vl best(2 * n, 1LL<<60);
best[1] = 0;
rep(i,1,best.size())
{
for (int j = 2; j * i < best.size(); j++)
best[j * i] = min(best[j * i], best[i] + ll(j - 1) * c + t);
}
cout << *min_element(best.begin() + n, best.end()) << endl;
return 0;
}
(看不懂就花点时间磨了)
Problem·2
题面
给出三个数列然后判断三个数列中某个数字a在另一个数字b前的数对有几个。
思路
我是怎么想的呢??
也只会暴力了,枚举与枚举。
然而会爆炸。
我还是太菜了,不适合大数据。
题解
代码
#include <iostream>
#include <stdio.h>
#include <vector>
using namespace std;
typedef long long ll;
typedef vector<ll> vl;
#define FOR(i,a,b) for (ll i = (a); i < (b); i++)
struct BIT {
ll n;
vl bit;
BIT(ll n): n(n) { bit.resize(n+2); }
void add(ll i, ll v) {
for (++i; i <= n+1; i += i & -i) bit[i] += v;
}
ll getSum(ll i) {
ll res = 0;
for (; i; i -= i & -i) res += bit[i];
return res;
}
};
ll same(vl a, vl b) {
ll n = a.size();
vl ai(n);
FOR(i,0,n) ai[a[i]] = i;
FOR(i,0,n) b[i] = ai[b[i]];
ll res = 0;
BIT bit(n);
FOR(i,0,n) res += bit.getSum(b[i]), bit.add(b[i],1);
return res;
}
int main() {
freopen("pairs.in", "r", stdin);
freopen("pairs.out", "w", stdout);
ll n; cin >> n;
vl a(n), b(n), c(n);
FOR(i,0,n) cin >> a[i], a[i]--;
FOR(i,0,n) cin >> b[i], b[i]--;
FOR(i,0,n) cin >> c[i], c[i]--;
cout << (same(a,b)+same(a,c)+same(b,c)-n*(n-1)/2)/2 << endl;
}
Problem·3
题面
给出一副棋盘上有四个旗子,每个可以向四个方向移一格或两格。再给出一幅图问最短移成所给图的步骤。
思路
dfs,秒想dfs。然后就GG了,写不出来…………还是需要锻炼一下代码能力。
题解
双向搜索
代码
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
const int dir[4][2]={{1,0},{0,1},{-1,0},{0,-1}};
const int MOD=1000007;
const int QSIZE=2000000;
struct Point {
char x, y;
};
struct EDGE {
Point p[4];
int next;
}edge[4000000];
int zh[2][MOD],etot;
EDGE q[2][QSIZE];
int front[2],rear[2];
bool cmp(Point a,Point b)
{
if(a.x!=b.x) {
return a.x<b.x;
}
return a.y<b.y;
}
bool same(Point s[],Point t[]) {
int i;
for(i=0;i<4;i++)
if(s[i].x!=t[i].x||s[i].y!=t[i].y) return 0;
return 1;
}
bool ok(char x,char n) {
return x > 0 && x <= n;
}
int GetCode(Point p[])
{
int i;
int ret=0;
for(i=0;i<4;i++) ret+=p[i].x*p[i].x+p[i].y*p[i].y;
return ret;
}
void ins(int zh[],EDGE x)
{
int hcode=GetCode(x.p);
edge[++etot]=x;
edge[etot].next=zh[hcode];
zh[hcode]=etot;
}
bool query(int zh[],EDGE x)
{
int hcode=GetCode(x.p);
for(int i=zh[hcode];i;i=edge[i].next)
if(same(x.p,edge[i].p))return 1;
return 0;
}
bool same(Point p[],Point t)
{
int i;
for(i=0;i<4;i++)
if(t.x==p[i].x&&t.y==p[i].y) return 1;
return 0;
}
bool BFS(Point s[],Point t[])
{
int step=0,size;
memset(zh,0,sizeof(zh));
front[0]=front[1]=-1;
rear[0]=rear[1]=0;
etot=0;
int i;
for(i=0;i<4;i++)
{q[0][0].p[i]=s[i];q[1][0].p[i]=t[i];}
int n=8;
if(same(s,t))return 1;
ins(zh[0],q[0][0]);
ins(zh[1],q[1][0]);
while(step<8)
{
int tag=(step&1);
size=rear[tag]-front[tag];
if(size<0)size+=QSIZE;
while(size--)
{
front[tag]++;
if(front[tag]>=QSIZE)front[tag]-=QSIZE;
int j;
for(i=0;i<4;i++)
{
for(j=0;j<4;j++)
{
Point tmp=
{q[tag][front[tag]].p[i].x+dir[j][0],q[tag][front[tag]].p[i].y+dir[j][1]};
if(!ok(tmp.x,n)||!ok(tmp.y,n))continue;
if(same(q[tag][front[tag]].p,tmp))
{tmp.x+=dir[j][0];tmp.y+=dir[j][1];}
if(!ok(tmp.x,n)||!ok(tmp.y,n))continue;
EDGE tq=q[tag][front[tag]];
tq.p[i]=tmp;
sort(tq.p,tq.p+4,cmp);
if(query(zh[1-tag],tq))return 1;
if(!query(zh[tag],tq)) {
ins(zh[tag],tq);
rear[tag]++;
if(rear[tag]>=QSIZE)rear[tag]-=QSIZE;
q[tag][rear[tag]]=tq;
}
}
}
}
step++;
}
return 0;
}
int main()
{
freopen("chess.in", "r", stdin);
freopen("chess.out", "w", stdout);
int n=4;
int i,j,k;
int x,y;
Point s[4],t[4];
while(scanf("%d%d",&x,&y) == 2) {
s[0].x=x;
s[0].y=y;
for(i=1;i<4;i++)
{
scanf("%d%d",&x,&y);
s[i].x=x;s[i].y=y;
}
sort(s,s+4,cmp);
for(i=0;i<4;i++)
{
scanf("%d%d",&x,&y);
t[i].x=x;t[i].y=y;
}
sort(t,t+4,cmp);
if(BFS(s,t))printf("YES\n"); else printf("NO\n");
}
return 0;
}
(确实长了点…………然后好像不是dfs,不过剪枝的dfs也是行的吧。)
上课的内容
各种搜索,深搜广搜,对抗搜;a*,ida*,剪枝搜;
大概这样吧,看看PPT就学学吧。