评价:比较简单的一集,简单考察思维和最基础算法
E:交互题。看了oiwiki和codeforces的文章,之前看的abc文章忘了,打算写一篇总结特点和一些典型例题,还了解了其他题型。
Solution:回到本题:只需要利用前缀和优化每次二分答案,从输入里得到我们想要的信息
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 void solve () { cin>>n; for (int i=1 ;i<=n;i++)cin>>a[i]; for (int i=1 ;i<=n;i++){ a[i]+=a[i-1 ]; } int l=1 ,r=n; while (l<r){ cout<<"?" <<" " ; int mid=(l+r)>>1 ; cout<<mid-l+1 <<" " ; for (int i=l;i<=mid;i++)cout<<i<<" " ; cout<<endl; int x;cin>>x; if (a[mid]-a[l-1 ]!=x)r=mid; else l=mid+1 ; } cout<<"!" <<" " <<l<<endl; }
F:题意:给定一个n ∗ m n*m n ∗ m 的矩阵,给定初始点的位置和速度方向,已经知道终点位置,问需要经过边界反射多少次才能到达终点?
Solution:对于反射问题不难想到周期,我们考虑最差情况第二次到达起点的时候遍历了所有方格点也就是n × m n\times m n × m 个点,算上初始方向,最多有四个方向,所以最多经历 4 × n × m 4\times n\times m 4 × n × m 的路程,意思是最大周期是这么多,再算下去一定会重复计算,没有意义。每次到边界的时候只需要判断速度和位置会不会导致下一步越界,如果越界,则速度取相反方向。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 void solve () { cin>>n>>m; int x1,y1,x2,y2;cin>>x1>>y1>>x2>>y2; string s;cin>>s; int mx=4 *n*m; int dx=0 ,dy=0 ; if (s[0 ]=='D' )dx=1 ; else dx=-1 ; if (s[1 ]=='R' )dy=1 ; else dy=-1 ; int cux=x1,cuy=y1; int cnt=0 ; while (mx--){ if (cux==x2&&cuy==y2){ cout<<cnt<<endl; return ; } bool flag=0 ; if (cux==1 &&dx==-1 )dx=1 ,flag=true ; if (cux==n&&dx==1 )dx=-1 ,flag=true ; if (cuy==1 &&dy==-1 )dy=1 ,flag=true ; if (cuy==m&&dy==1 )dy=-1 ,flag=true ; cux+=dx;cuy+=dy; if (flag)cnt++; } cout<<-1 <<endl; }
G:题意:Subsequence Addition (Hard Version)
数列 a a a 最开始只有一个数 1 1 1 ,你可以进行若干次操作,每次操作你可以选取最新数组中 k k k 个数(k k k 无限制,小于等于 a a a 的大小即可),将这 k k k 个数的和放入 a a a 的任意一个位置。
给定一个长度为 n n n 的序列 c c c ,问 a a a 能否在进行n-1次操作后转为 c c c 。
有 t t t 组数据。
1 ≤ ∑ n ≤ 2 × 1 0 5 , 1 ≤ c i ≤ 2 × 1 0 5 , 1 ≤ t ≤ 1000 1\leq \sum n\leq2\times10^5,1\leq c_i\leq2\times10^5,1\leq t\leq1000 1 ≤ ∑ n ≤ 2 × 1 0 5 , 1 ≤ c i ≤ 2 × 1 0 5 , 1 ≤ t ≤ 1 0 0 0
Solution:由于是子序列,发现排序不影响答案正确性。以背包视角思考问题,可以发现只要前i-1小
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 int n, m;int a[N]; void solve () { cin>>n; for (int i=1 ;i<=n;i++)cin>>a[i]; int sum=1 ; bool flag=true ; sort (a+1 ,a+1 +n); for (int i=1 ;i<=n;i++){ if (a[i]>sum)flag=false ; if (i>1 ) sum+=a[i]; } if (flag)cout<<"YES" <<endl; else cout<<"NO" <<endl; }