还有一半的时间逃出来开始写总结(难题太难不会做溜了溜了)
一A了两个水题,还是比较欣慰,最少比原来的连水题都疯狂wa进步很多,但是难题还是没思路,有思路代码不会实现。
此外,觉得水题虽水,但也需要运用技巧,像E题,hint 中重要的事情说三遍写出了 题目对空间大小的限制 2MB ,显然开数组绝对会炸,写完了开数组排序取中值就觉得不对,立刻换思路,不开数组解决。
E题AC代码: (一个求多余一半的数的个数的问题)
//
// main.cpp
// 2_E
//
// Created by 陈冉飞 on 2019/6/2.
// Copyright © 2019 陈冉飞. All rights reserved.
//
#include
using namespace std;
int main(int argc, const char * argv[]) {
int total;
scanf("%d",&total);
int res = 0,cnt = 0,num;
for (int i = 0; i
这次的D题,同样也是一道水题,最一开始看到别人疯狂a 自己却一点思路都没有慌的一批,后来一想,怎么都是菜,不会做就不会做了,冷静下来思考了一下就是逐次选取偶数,每次对n进行除二的操作,除出来的数即为偶数,即可以提取的k,给他加到ans 中。最后再输出ans即可。
D题AC代码:
//
// main.cpp
// 2_D
//
// Created by 陈冉飞 on 2019/6/2.
// Copyright © 2019 陈冉飞. All rights reserved.
//
#include
using namespace std;
#define ll long long
int main(int argc, const char * argv[]) {
ll int n,ans = 0;
scanf("%lld",&n);
while (n>=2) {
if (n%2 == 0) {
ans+=n/2;
}
else{
n--;
ans+=n/2;
}
n/=2;
}
cout<
附加AB题的题解:
A题:
-csuoj2334 正解是Bfs+剪枝。好像不剪枝直接Bfs爆搜也能过??? Bfs: 直接枚举每个方向的速度bfs搜索下去即可。 剪枝:在状态拓展过程中可以去掉一些重复无用的搜索。走一条线的时候,如果出现了前方有一个位子(x,y,z),使得从起点走到这个点的时间小于等于当前点时间的话,无需继续向那个方向继续走了。因为那个方向的取优方案可以通过点(x,y,z)来更新,所以多余步骤可以删除。同时如果搜索到终点的话也可直接退出。
代码:
#include
#include
#include
#include
using namespace std;
char s[110][110][110];
int dp[110][110][110],dx[]={0,0,1,-1,0,0},dy[]={1,-1,0,0,0,0},dz[]={0,0,0,0,-1,1},n,m,l,w;
struct Q{
int x,y,z;
}u,v,ss,tt;
queueq;
void bfs(){
int i,j;
memset(dp,33,sizeof(dp));
dp[ss.z][ss.x][ss.y]=0;
while(!q.empty()) q.pop();
for(q.push(ss);!q.empty();q.pop()){
u=q.front();
if(u.x==tt.x&&u.y==tt.y&&u.z==tt.z) break;
for(i=0;i<6;i++){
for(j=1;j<=w;j++){
v.x=u.x+dx[i]*j;
v.y=u.y+dy[i]*j;
v.z=u.z+dz[i]*j;
if(v.x<0||v.x>=n||v.y<0||v.y>=m||v.z<0||v.z>=l) break;
if(s[v.z][v.x][v.y]=='#'||dp[v.z][v.x][v.y]<=dp[u.z][u.x][u.y]) break;
if(dp[v.z][v.x][v.y]>dp[u.z][u.x][u.y]+1){
dp[v.z][v.x][v.y]=dp[u.z][u.x][u.y]+1;
q.push(v);
}
}
}
}
if(dp[tt.z][tt.x][tt.y]<=1e6) printf("%d\n",dp[tt.z][tt.x][tt.y]);
else printf("-1\n");
}
int main(){
int i,j,k,t;
scanf("%d",&t);
while(t--){
scanf("%d%d%d%d",&n,&m,&l,&w);
for(k=0;k
B题:
csuoj2336 由于只考虑出现次数的奇偶,所以可以处理出一个26位的二进制数来表示每个字符串,表示每个字母出现次数的奇偶。然后问题就转为求有多少个子集的异或值为0。很容易想到枚举每个子集,但子集数会有2^n个,直接枚举在这题里是过不了的。 这里需要将字符串分为两部分,再分别枚举这两部分的子集的xor值,用个map记录每个xor值的出现次数,这样时间复杂度就降为了 log n * 2^(n/2) 了。
代码:
#include
#include
#include
#include
F题:
数学推导:
x2+y2=r2
⇒y2=(r−x)(r+x)
令d=gcd(r−x,r+x)
则y2=d2∗r+xd∗r−xd
再令A=r+xd,B=r−xd
则y2=d2∗A∗B
考虑y2是完全平方数,d2是完全平方数,又gcd(A,B)=1那么A,B都是完全平方数。
设A=a2,B=b2
A+B=a2+b2
⇒2∗rd=a2+b2
考虑枚举2∗rd,这一步的复杂度是O(r√)的,然后再在[1,2∗rd‾‾‾‾‾√/2]的范围内枚举a,进而可以算出A,b,B,然后判断A,B是否互质,B是否为完全平方数,这样子就算出了第一象限的答案,然后将ans∗4+4,算是统计了每一个象限的并且加上了坐标轴上的四个点。
代码:
#include
#include
#include
#include
#include
#include
#include
#include
#include