solve:4/11

补题:6/11

A 机器人

补题:zz

这是一道分类讨论的题目,有一个规律就是如果必须要从第一个区到第二个区,那么最多转区两次(1到2一次,2到1一次),然后分类讨论即可,只要细心一定能做出来。

//#pragma comment(linker, "/STACK:102400000,102400000")
#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<string>
#include<math.h>
#include<cmath>
#include<time.h>
#include<map>
#include<set>
#include<vector>
#include<queue>
#include<algorithm>
#include<numeric>
#include<stack>
#include<bitset>
#include<unordered_map>
const int maxn = 0x3f3f3f3f;
const double EI = 2.71828182845904523536028747135266249775724709369995957496696762772407663035354594571382178525166427;
const double PI = 3.141592653589793238462643383279;
//#ifdef TRUETRUE
//#define gets gets_s
//#endif
using namespace std;
int c[][];
int z[][], cnt[];
int d[];
int main(void)
{
//ios::sync_with_stdio(false);
int n, rr, k, m, s, i, x, y, l1, l2, r1, r2, ans, l, r, j;
while (~scanf("%d %d %d %d %d", &n, &rr, &m, &k, &s))
{
memset(c, , sizeof(c));
cnt[] = ;
cnt[] = ;
for (i = ; i < rr; i++)
{
scanf("%d %d", &x, &y);
if (x == s && y == )
{
continue;
}
c[y][x] = ;
z[y][cnt[y]++] = x;
}
for (i = ; i < m; i++)
{
scanf("%d", d + i);
}
sort(z[], z[] + cnt[]);
sort(z[], z[] + cnt[]);
l1 = -;
l2 = -;
r1 = -;
r2 = -;
if (cnt[])
{
l1 = z[][];
r1 = z[][cnt[] - ];
}
if (cnt[])
{
l2 = z[][];
r2 = z[][cnt[] - ];
}
ans = ;
if (l2 != -)
{
ans += k * ;
}
l = min(l1, l2);
if (l1 == -)
{
l = l2;
}
else if (l2 == -)
{
l = l1;
}
r = max(r1, r2);
d[m++] = ;
d[m++] = n;
d[m++] = n + ;
sort(d, d + m);
/*for (i = 0;i < m;i++)
{
printf("%d ", d[i]);
}
printf("\n");*/
//printf("l = %d r = %d\n", l, r);
if (r <= s && r != - && l != -)
{
//printf("l = %d r = %d\n",l,r);
for (i = ; i < m; i++)
{
if (d[i] <= l && d[i + ] > l)
{
break;
}
}
ans += s - d[i];
//printf("ans = %d\n",ans);
if (l2 != -)
{
for (j = ; j < m; j++)
{
if (d[j] >= r2)
{
break;
}
}
ans += d[j] - d[i];
ans += abs(s - d[j]);
}
else
{
ans += s - d[i];
}
}
else if (l >= s && r != - && l != -)
{
for (i = ; i < m; i++)
{
if (d[i] >= r)
{
break;
}
}
ans += d[i] - s;
if (l2 != -)
{
for (j = m - ; j >= ; j--)
{
if (d[j] <= l2)
{
break;
}
}
ans += d[i] - d[j];
ans += abs(s - d[j]);
}
else
{
ans += d[i] - s;
}
}
else if (l <= s && r >= s && r != - && l != -)
{
for (i = ; i < m; i++)
{
if (d[i] <= l && d[i + ] > l)
{
break;
}
}
//printf(" %d\n",ans);
ans += * (s - d[i]);
//printf(" %d %d %d %d %d\n", ans,d[i],i,l,r);
for (i = ; i < m; i++)
{
if (d[i] <= r && d[i + ] >= r)
{
break;
}
}
ans += * (d[i + ] - s);
//printf(" %d %d\n", ans,d[i + 1]);
}
printf("%d\n", ans);
}
return ;
}

B 吃豆豆

Code:pai爷

Thinking: pai爷  KK

dp[ i ][ j ][ k ]表示 i 行 j 列 在第 k 秒的时候吃到的最多的豆豆数量,从五个方向转移(上下左右加自己)。k的范围最大只有1018*10,然后用滚动数组滚动掉,就可以AC了。

补充:div1 1018变成了10^18,会有周期,尚未证明,k,k+t,k+2t。

#include<stdio.h>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<cmath>
using namespace std;
int ans=,n,m,c,now=,X1,X2,Y1,Y2,f[][][],t[][];
void solve(int a,int b,int c,int d,int k) {
if(t[a][b]!= && (k%t[a][b]==)) f[!now][a][b]=max(f[now][c][d]+,f[!now][a][b]);
else f[!now][a][b]=max(f[now][c][d],f[!now][a][b]);
}
int main() {
scanf("%d%d%d",&n,&m,&c);
for(int i=; i<=n; i++)
for(int j=; j<=m; j++) scanf("%d",&t[i][j]);
scanf("%d%d%d%d",&X1,&Y1,&X2,&Y2);
for(int k=; k<=; k++)
for(int i=; i<=n; i++)
for(int j=; j<=m; j++) f[k][i][j]=-;
f[now][X1][Y1]=;
for(int k=; k<=; k++) {
for(int i=; i<=n; i++)
for(int j=; j<=m; j++)
if(f[now][i][j]!=-) {
solve(i+,j,i,j,k);
solve(i-,j,i,j,k);
solve(i,j+,i,j,k);
solve(i,j-,i,j,k);
solve(i,j,i,j,k);
if(f[!now][X2][Y2]>=c) ans=k;
}
if(ans) break;
now=!now;
}
printf("%d\n",ans);
}

C  拆拆拆数

unsolved

D 超难的数学题

unsolved

E 流流流动

补题:kk

树形dp,比赛没人做,以为是难题。

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
#define CLR(a,b) memset(a,b,sizeof(a));
using namespace std;
typedef long long ll;
const int inf=0x3f3f3f3f;
const int maxn=;
int head[maxn],tot,n;
bool vis[maxn];
int f[maxn],d[maxn];
int dp[][maxn];
struct edge{
int v,Next;
}a[maxn<<];
void init(){
tot=,CLR(head,-);
CLR(vis,false);
CLR(dp,);
}
void addv(int u,int v)
{
a[++tot].v=v;
a[tot].Next=head[u];
head[u]=tot;
}
void tdfs(int u,int fa){
int flag=;
vis[u]=;
dp[][u]=;
dp[][u]=f[u];
for(int i=head[u];i!=-;i=a[i].Next)
{
int v=a[i].v;
if(v==fa)continue;
tdfs(v,u);
flag=;
dp[][u]+=max(dp[][v],dp[][v]);
dp[][u]+=max(dp[][v],dp[][v]-d[min(u,v)]);
}
}
int main(){
cin>>n;
init();
for(int i=;i<=n;i++)
{
scanf("%d",&f[i]);
}
for(int i=;i<=n;i++)
{
scanf("%d",&d[i]);
}
for(int i=;i<=n;i++)
{ if(i%==)
{
addv(i,*i+);
addv(*i+,i);
}
if(i%==){
addv(i,i/);
addv(i/,i);
}
}
int ans=;
for(int i=;i<=n;i++)
{
if(vis[i]==){
tdfs(i,);
ans+=max(dp[][i],dp[][i]);
}
}
printf("%d\n",ans);
}

F 爬山

Code:KK

Thinking:KK

对于一座山,如果要砍,就肯定要砍到(K+第一座山的高度),将这部分额外的花费加到边的权值上就好了,双向边要分开建,权值不一定一样,然后dijkstra跑一跑,水题。

 #include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<string>
#include<math.h>
#include<cmath>
#include<time.h>
#include<map>
#include<set>
#include<vector>
#include<queue>
#include<algorithm>
#include<numeric>
#include<stack>
#include<bitset>
//#include<unordered_map>
const int inf = 0x3f3f3f3f;
const double EI = 2.71828182845904523536028747135266249775724709369995957496696762772407663035354594571382178525166427;
const double PI = 3.141592653589793238462643383279;
const int maxn=;
using namespace std;
typedef long long ll;
int n,m;
ll k;
int head[maxn],tot;
ll dis[maxn]; struct edge{
int v;
ll w;
int Next;
}a[maxn<<];
bool vis[maxn];
ll h[maxn];
void init(){
tot=,memset(head,-,sizeof(head));
}
void addv(int u,int v,ll w)
{
a[++tot].v=v;
a[tot].w=w;
a[tot].Next=head[u];
head[u]=tot;
}
priority_queue< pair<ll,int>>q;
void dijkstra(){
memset(vis,false,sizeof(vis));
memset(dis,0x3f,sizeof(dis));
dis[]=;
q.push(make_pair(,));
while(!q.empty()){
int x=q.top().second;
q.pop();
if(vis[x])continue;
vis[x]=;
for(int i=head[x];i!=-;i=a[i].Next)
{
int y=a[i].v;
ll w=a[i].w;
if(dis[y]>dis[x]+w){
dis[y]=dis[x]+w;
q.push(make_pair(-dis[y],y));
}
}
}
}
int main(void)
{
//ios::sync_with_stdio(false);
cin>>n>>m>>k;
init();
scanf("%lld",&h[]);
k+=h[];
for(int i=;i<=n;i++)
{
scanf("%lld",&h[i]);
}
int u,v;
ll w;
while(m--)
{
scanf("%d%d%lld",&u,&v,&w);
if(h[v]>=k)
addv(u,v,w+(h[v]-k)*(h[v]-k));
else addv(u,v,w);
if(h[u]>=k)
addv(v,u,w+(h[u]-k)*(h[u]-k));
else addv(v,u,w);
}
dijkstra();
printf("%lld\n",dis[n]);
return ;
}

G  双重矩阵

unsolved

H 我爱割葱

unsolved

I 起起落落

Code:pai爷

Thinking:pai爷

div 2 树状数组+dp思想 O(n*n*log(n))

 #include<stdio.h>
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
using namespace std;
const int P=1e9+;
int n,p[],w[],c[],q[][];
int ans=;
inline int lowbit(int x){return x&-x;}
void add(int x,int y)
{
for(;x<=n;x+=lowbit(x)) c[x]=(c[x]+y)%P;
}
int sum(int x)
{
int tmp=;
for(;x;x-=lowbit(x)) tmp=(tmp+c[x])%P;
return tmp;
}
int main()
{
scanf("%d",&n);
for(int i=;i<=n;i++) scanf("%d",&p[i]);
for(int i=;i<=n;i++)
for(int j=i+;j<=n;j++)
{
if(p[i]<p[j])
{
q[i][]++;
q[i][q[i][]]=j;
//printf("%d %d\n",i,j);
}
}
for(int i=n;i>=;i--)
{
w[i]=sum(p[i]-);
ans=(ans+w[i])%P;
//printf("%d\n",ans);
w[i]++;
for(int j=;j<=q[i][];j++) add(p[q[i][j]],w[q[i][j]]);
}
printf("%d\n",ans);
}

J 夺宝奇兵

Code:zz

Thinking:KK zz

div2:由于m最大只有一千,所以从(m+1)/2到1枚举最后我需要买的物品,每次和当前答案更新。如一个人的物品比自己需要买的多或一样多,那肯定先把多余这部分的全部买走,如果发现不够,那么就在剩下的所有里面挑最便宜的;如果发现买完那些比自己大的,就已经超出当前的值了,说明不合法,就不更新答案。用multiset完成以上操作。

div1:m变成一万,不能枚举,想到二分,发现中间有一段区间虽然都是合法的,但是并不是买的物品越少钱越少(买的物品多了,强制买的物品就少,然后不足的就可以从其他物品里挑最便宜的),所以不满足二分的性质,三分好像可以做(wls吐槽好像二字),标算是线段树?还不会。

 //#pragma comment(linker, "/STACK:102400000,102400000")
#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<string>
#include<math.h>
#include<cmath>
#include<time.h>
#include<map>
#include<set>
#include<vector>
#include<queue>
#include<algorithm>
#include<numeric>
#include<stack>
#include<bitset>
//#include<unordered_map>
const int inf = 0x3f3f3f3f;
const int maxn=;
using namespace std;
typedef long long ll;
struct s
{
long long c[];
int cnt;
}z[];
multiset<long long>st;
multiset<long long>::iterator it;
inline bool comp(ll a,ll b)
{
return a > b;
}
int main(void)
{
//ios::sync_with_stdio(false);
int n,m,i,z2,j,num,x,k;
long long z1,sum,ans,ss;
while(~scanf("%d %d",&n,&m))
{
st.clear();
for(i = ;i <= n;i++)
{
z[i].cnt = ;
}
for(i = ;i < m;i++)
{
scanf("%lld %d",&z1,&z2);
z[z2].c[z[z2].cnt++] = z1;
st.insert(z1);
}
for(i = ;i <= n;i++)
{
sort(z[i].c,z[i].c + z[i].cnt,comp);
}
sum = ;
num = ;
ans = ;
for(i = m / + ;i >= ;i--)
{
for(j = ;j <= n;j++)
{
if(z[j].cnt >= i)
{
while(z[j].cnt >= i)
{
num++;
sum += z[j].c[z[j].cnt - ];
st.erase(st.find(z[j].c[z[j].cnt - ]));
z[j].cnt--;
}
}
}
if(num == i)
{
ans = min(sum,ans);
}
else if(num < i)
{
ss = sum;
x = i - num;
for(it = st.begin();it != st.end();it++)
{
sum += *it;
x--;
if(x == )
{
break;
}
}
ans = min(sum,ans);
sum = ss;
}
}
printf("%lld\n",ans);
}
return ;
}

K 星球大战

unsolved

建bfs树

训练总结:

KK: 简单dp听了pai爷的一些思路马上意会到正解。最短路看错样例,看清后秒解,然后oj的排名炸了,以为今天只能做两题,所以在梦游想题,后来发现J题数据量小,想了一下想到div2的正解,被zz优化了一下,刚好过了,自己写可能会wa一发(因为没有二分的性质,但是自己写可能会找到一个答案就直接break),以后训练要认真,很多题都是可以思考的,不到最后不要放弃。

pai爷:做题的时候缺少验证吧,不够认真对待题目,思路要清晰,想法很多,错误想法也很多。之后要大胆猜测以及大胆验证。

zz:一开局看到了B,感觉和以前做的一道题很像,想到可能是一个三重循环的dp,但是时间那一维和状态转移方程没想好,就没说,看其他题去了;后来oj出了问题,基本上没更新,题目基本上没什么思路,过了很久以后,kk跟我说了J题的暴力做法,我看了看n和m才一千,感觉行,后来在写的时候发现太暴力是要n^3的,就用multiset降到了n*n*log(n),刚好过(因为comp函数写错了wa了,哭了)。

2019 CCPC-Wannafly Winter Camp Day1 (Div2, onsite)的更多相关文章

  1. 2020 CCPC Wannafly Winter Camp Day1 C. 染色图

    2020 CCPC Wannafly Winter Camp Day1 C. 染色图 定义一张无向图 G=⟨V,E⟩ 是 k 可染色的当且仅当存在函数 f:V↦{1,2,⋯,k} 满足对于 G 中的任 ...

  2. CCPC-Wannafly Winter Camp Day1 (Div2, onsite) A B C E F I J

    A 机器人 链接:https://www.cometoj.com/contest/7/problem/A?problem_id=92 思路: 分两大类讨论: 1. B区没有点: (1)点都在起点左边 ...

  3. CCPC-Wannafly Winter Camp Day1 (Div2, onsite)

    Replay Dup4: 要是不挂机,再多仔细想想就好了 J确实自闭好久,一直在想正确性,最后数据错了,喵喵喵? 还是要保证充足的休息啊,中间睡了一小会儿,也不知道睡了多久,醒来他们就又过了一道 要发 ...

  4. CCPC-Wannafly Winter Camp Day1 (Div2, onsite) - I 起起落落

    题目描述 无聊的wlswls正在观察某个商品的价格,wlswls一共观察了nn天,每天这个商品都会有一个价格p_ipi​. 定义一个长度为2m+1(3\leq2m+1\leq n)2m+1(3≤2m+ ...

  5. CCPC-Wannafly Winter Camp Day1 (Div2, onsite) 夺宝奇兵

    题目描述 wlswls所在的王国有nn个居民(不包括wlswls),他们共有mm件神奇的宝物. 对于第ii件宝物,wlswls可以花费a_iai​的金币把它从原来的主人那里买过来. 请问wlswls最 ...

  6. 2020 CCPC Wannafly Winter Camp Day1 Div.1&amp F

    #include<bits/stdc++.h> #define forn(i, n) for (int i = 0; i < int(n); i++) #define fore(i, ...

  7. 2020 CCPC Wannafly Winter Camp Day1 - I. K小数查询(分块)

    题目链接:K小数查询 题意:给你一个长度为$n$序列$A$,有$m$个操作,操作分为两种: 输入$x,y,c$,表示对$i\in[x,y] $,令$A_{i}=min(A_{i},c)$ 输入$x,y ...

  8. CCPC-Wannafly Winter Camp Day1 (Div2 ABCFJ) 待补...

    Day1 Div2 场外链接 按题目顺序~ A 机器人 传送门 题意:有两条平行直线A.B,每条直线上有n个点,编号为1~n.在同一直线上,从a站点到b站点耗时为两点间的距离.存在m个特殊站点,只有在 ...

  9. 2019 CCPC-Wannafly Winter Camp Day7(Div2, onsite)

    solve 6/11 补题: A.迷宫 Code:zz Thinking:zz kk 把每个节点的深度都处理出来,同一深度的点的冲突度为 (x-1),x为同层次点数减一. 然后冲突度不断下传(冲突度为 ...

随机推荐

  1. Verifying Package Integrity Using MD5 Checksums or GnuPG

    In this note, I reference the MySQL manual file. After downloading the MySQL package that suits your ...

  2. 清北学堂 day6 兔子

    ---恢复内容开始--- [问题描述] 在一片草原上有N个兔子窝,每个窝里住着一只兔子,有M条路径连接这些窝.更特殊地是,至多只有一个兔子窝有3条或更多的路径与它相连,其它的兔子窝只有1条或2条路径与 ...

  3. spring.net事件的注入

    .c#代码 TestObject source = new TestObject(); TestEventHandler eventListener1 = new TestEventHandler() ...

  4. 不使用库函数sqrt实现求一个数的平方根

    二分法: double mysqrt(double a) { ) ; , end = a; ) end = ; while(end - start > precision) { ; if( mi ...

  5. 42 :809*x=800*x+9*x+1

    题目:809*x=800*x+9*x+1(去掉最后的1有解)其中x代表的两位数,8*x的结果为两位数,9*x的结果为3位数.求x代表的两位数,及809*x后的结果(两种方法实现) public cla ...

  6. java.lang.ClassCastException: com.liuyang.annocation.UserAction cannot be cast to com.liuyang.annocation2.UserAction at com.liuyang.annocation2.App.test

    java.lang.ClassCastException: com.liuyang.annocation.UserAction cannot be cast to com.liuyang.annoca ...

  7. SpringMVC错误集中营

    1.eclipse里的错误提示为The import javax.servlet.http.HttpServletRequest cannot be resolved 1.这是因为工程里面web-in ...

  8. Arduino I2C + 温湿度传感器Si7021

      Si7021是Silicon Labs生产的温湿度传感器芯片.其主要特性: 湿度精度:误差典型值+/-2%RH,最大值+/-3%RH(0~80%RH),出厂已校正 温度精度:误差典型值+/-0.3 ...

  9. C#面向对象的三大基本特征

    封装: 封装是指将数据与具体操作的实现代码放在某个对象内部,使这些代码的实现细节不被外界发现(可以使代码更加安全),外界只能通过接口使用该对象,而不能通过任何形式修改对象内部实现,正是由于封装机制,程 ...

  10. windbg符号路径设置

    .sympath C:\Users\leoyin\Desktop\last;SRV*C:\Symbols*http://msdl.microsoft.com/download/symbols