以前写的弱智玩意

以前写的弱智玩意(算笔记吧)收拾电脑找到的 是不是应该私密下233



2017_3_15

!优先级高于%*/,与+-(代表符号而不是加减运算)同级
实例:if(n%100&&!(n%4)||!(n%400))
if(n%100&&!n%4||!n%400)
1对2错
如果不加括号程序会对n取反即0为1,非0为0,然后进行取余运算,结果自然出错。


三角函数返回值是 double


Pi值尽量多写几位,不然可能出错
#define Pi 3.14159265358979


abs函数返回值是int!int!int!
重要的事情说三遍
fabs()能用。话说不就是把1变成0嘛,弄这么麻烦干啥。


2017_3_16
pow函数返回值是double,
计算指数时
不能写成 printf("%d",pow(2,2);
而要写成 printf("%.f",pow(2,2);
备注:要算以2为底的指数时,可以写成1 << n 既是结果,可以用int


int 可以用%c存数据,不过是字符(ASC)方式存的




2017_3_17
计算机杂谈:
风语 2017/3/17 19:47:55
显哥在不
有个问题想问你
#include<stdio.h>
#include<string.h>
char a[10];
int main(){
    memset(a,0,sizeof(a));
    int i = 0;
    while(!a[i]){
        printf("%d ",i);
        i++;
    }
    return 0;
}
#include<stdio.h>
#include<string.h>
int main(){
    char a[10];
    memset(a,0,sizeof(a));
    int i = 0;
    while(!a[i]){
        printf("%d ",i);
        i++;
    }
    return 0;
}


风语 2017/3/17 19:49:22
为什么第一个会一直输出到31而第二个输出到9呢


大佬 2017/3/17 20:40:11
我看看下,刚上课回来


大佬 2017/3/17 20:43:00
...你这两个代码有区别么,,,


风语 2017/3/17 20:43:06

第一个输出一直到31
第二个一直输出到9


大佬 2017/3/17 20:44:27
哦哦,两个char数组位置不一样


风语 2017/3/17 20:44:33

第一个在主函数外面


大佬 2017/3/17 20:47:17
你第一个开个 33 看一下
告诉我输出多少


风语 2017/3/17 20:47:37
83


大佬 2017/3/17 20:49:00
感觉和堆栈有关


大佬 2017/3/17 20:50:03
我们的计算机的硬盘(也就是存储空间)是由无数的最小单位的存储器组成,
你记不记得,宇哥第一次讲课的时候说过,开特别大的数组要开在函数外


风语 2017/3/17 20:51:07
嗯嗯 在函数外面是堆存储


大佬 2017/3/17 20:51:32
否则会爆栈-->说明,这时候程序代码和数据是存在初期开的一块栈里


大佬 2017/3/17 20:53:26
我们的c,c++属于静态语言,也就是必须在声明定义的时候,必须预编译告诉计算机你需要多大内存,然后试着开一下,开不出来,即爆栈,return error
然而你在程序外面开的话,是新开辟的一块空间
大佬 2017/3/17 20:55:14
这和硬件有关,我们的寄存器在X64情况下,最小是开一个int,也就是4char
一个字节,8个bit,由于没有使用,so,是干净的,即使memset函数,我觉得也是可以输出到31的
即使没有使用memset函数


风语 2017/3/17 20:57:29
嗯嗯 memset 删了也是31


大佬 2017/3/17 20:57:46
你可以试试,先将这十个元素置为a,输出 a[i]=='a',看看,是不是输出到10


大佬 2017/3/17 20:59:34
说错了,应该是9...


风语 2017/3/17 20:59:46
哈哈哈
没错


风语 2017/3/17 20:59:52
是9


大佬 2017/3/17 21:00:19
so,我说明白了么...


一句话总结:数组越界……




2017_3_18
#include<limits.h>
作用:limits.h专门用于检测整型数据数据类型的表达值范围。
例:
INT_MAX
INT_MIN


结构体定义
http://blog.****.net/xiaoyali/article/details/4393486
结构体排序
http://blog.****.net/martinue/article/details/51758888


struct data{
    int x;
    int y;
} a[3];
bool cmp1(data m,data n){//x升序
    return m.x <n.x;
}
bool cmp2(data m,data n){//y降序
    return m.y > n.y;
}
bool cmp3(data m,data n){//先x升序,若x相等,则按y升序
    if(m.x==n.x)
        return m.y<n.y;
    return m.x<n.x;
}
sort(a,a+3,cmp);




2017_3_19
关于sort()函数
http://blog.****.net/ajioy/article/details/6976945
https://zhidao.baidu.com/question/216527176.html




2017_3_20
随堂笔记:关于算法优化的一点启示:
例如水仙花数:一个三位数abc=a*a*a+b*b*b+c*c*c既是水仙花数。
不难想到的算法是将一个整数通过取整取余等等等转化为三个整数,然后做立方和。固然,这种方式是可以的,因为只有三位,怎样算都不会超时。可如果是11位以上,甚至超过long long的最大值呢?
这时,便可以用gets(或scanf)读入一个字符串,直接将字符串各字符立方(减48),这样,就解决了整数最大值的限制问题。
但是,又一个问题出现了:不管是a*a*a,还是pow(a,3),都会耽误大量的时间。这是,完全可以用switch,将每一种情况并列出来,这样,每一次运算的复杂度就只是o(n),
在上亿之前,应该是都可以跑出来的。(百度了一发后,发现pow函数的实现方式并不简单,是用泰勒展开算出来的,要是只考虑3次方的话,t(pow)>t(a*a*a)>t(pow));
pow函数要慎用!认真脸 0.0
sin啦 cos啦 好像都是用泰勒公式写的,嗯嗯。




2017_3_25
这几天都为cccc准备,脑子乱乱的,没写啥
getchar();很重要!!!(认真脸)
比赛时后遇到一个题,虽然过了,但是做法很麻烦。其实就是基于字符串和数字的相互转换。
http://www.cnblogs.com/bluestorm/p/3168719.html
http://blog.sina.com.cn/s/blog_4c8a2a870100qgq7.html
1.int/float to string/array:
C语言提供了几个标准库函数,可以将任意类型(整型、长整型、浮点型等)的数字转换为字符串,下面列举了各函数的方法及其说明。
● itoa():将整型值转换为字符串。itoa(int *,char *,10)10表示进制
● ltoa():将长整型值转换为字符串。
● ultoa():将无符号长整型值转换为字符串。
● gcvt():将浮点型数转换为字符串,取四舍五入。
● ecvt():将双精度浮点型值转换为字符串,转换结果中不包含十进制小数点。
● fcvt():指定位数为转换精度,其余同ecvt()。
除此外,还可以使用sprintf系列函数把数字转换成字符串,其比itoa()系列函数运行速度慢
2. string/array to int/float
C/C++语言提供了几个标准库函数,可以将字符串转换为任意类型(整型、长整型、浮点型等)。
● atof():将字符串转换为双精度浮点型值。
● atoi():将字符串转换为整型值。
● atol():将字符串转换为长整型值。
● strtod():将字符串转换为双精度浮点型值,并报告不能被转换的所有剩余数字。
● strtol():将字符串转换为长整值,并报告不能被转换的所有剩余数字。
● strtoul():将字符串转换为无符号长整型值,并报告不能被转换的所有剩余数字。
感觉有好多……慢慢研究吧








2017_3_26
strcmp(字符串比较函数):
http://c.biancheng.net/cpp/html/162.html
strcoll
http://c.biancheng.net/cpp/html/163.html
从第一个字符向下扫逐个比较
strcmp(a,b);
a==b return 0
a>b  return>0
a<b  return<0
不一定是1 0 -1








2017_3_27
strcpy函数:
strcpy(a,b);
把字符串b的值赋给a;
#include <string.h>
#include<stdio.h>
int main(){
    char a[2];
    char b[10] = "12345678";
    strcpy(a, b);
    printf("%d", a[2]);
    return 0;
}
//注意:输出结果为3;输出结果是正确的,但是这种方式不可取,因为它将会改变后面的内存中的值。






2017_3_31
#include<stdio.h>
#include<stack>
#include<queue>
using namespace std;
int main(){
    stack<int> a;
    queue<int> b;
    a.push(1);
    b.push(1);//压入数据
    
    a.size();
    b.size();//长度
    
    b.front();//队列头
    b.back();//队列尾
    
    a.top();//栈顶
    
    a.pop();//移除栈顶元素
    b.pop();//移除队列头
    
    a.empty();
    b.empty();//判断是否为空,空1非空0


    return 0;
}
当栈或队列为空时,使用front,back,top,pop会导致程序崩溃
妈个鸡,链表居然还有头文件:#include<list>
可网上也说了,头文件里的链表没有自己写的效率高。。。
那也就是说,栈和队列应该也可以自己实现。。。

妈个鸡。。。


2017年4月2日21:12:51
存二进制可以bool存


2017年4月4日14:58:01
int 不能用%lld输出




2017年4月7日20:11:09
多边形面积(包含凹多边形):
思路:将n边形分成n-1个三角形,每个顶点坐标既是从o点到该点的向量,之后利用叉乘算三角形面积。看图。








2017年4月8日19:23:58
补了一个题(大傻和小伙伴,cf上的),a了之后看别人代码的时候发现了一个很巧妙的环形数组;a[i%n],n是数组长度






2017年4月9日11:26:30
cin cout:
http://blog.****.net/zhanghaotian2011/article/details/8868577
http://blog.****.net/maweiqi/article/details/7950366
还挺好玩的 就是用不惯






2017年4月10日22:28:39
算逆序对数:
归并
4 3 2 1
分开后:
4 3    2 1
子序列排序:
3 4    1 2   这时会产生逆序对; 此时ans = 2;
对3 4 1 2排序:
1 < 3 ans += 2;加的是提前的距离。
2 < 4 ans += 2;
ans = 6;






Atcoder Beginner Contest 058题解:
if(着急)
goto pp;
比赛时候没做出来。。。不开心。。。
比赛的时候,一开始受样例的影响,以为可以用m,n找出和总面积之间的关系,例如2*2的方格,只需要把面积算四次,就是所要求的答案。但是想到了一种反例:例如,在一个3*2的方格中,位于两侧的方格算面积的次数会比中间的少算一次,这样形成的就不是完整的面积了。这个思路走不通。。。然后。。。有题解,嗯。。。题解看不懂。。。求和什么鬼。。。但是题解提醒了我可以用o(n+m)的复杂度算出来,经过一番冥思苦想之后


pp:
思路:不必求出所有矩形面积之后加和,只要求出每个矩形算面积长/宽的次数
求法:
看图;
另外,这个数最后的结果还要对一个数取余,同样的思路,每一次循环加一个取余就可以了。
看例子:
#include<iostream>
using namespace std;


int main(){


    int a = 155 % 15;
    int b = 167 % 15;
    int c = (a + b) % 15;


    cout << a << endl;
    cout << b << endl;
    cout << c << endl;


    return 0;
}


输出结果是:
5
2
7
这玩意有个名字 叫同余模定理:
http://blog.****.net/qq_29600137/article/details/50821993
公式:
(a+b)%c=(a%c+b%c)%c;
(a*b)%c=(a%c*b%c)%c;








2017年4月12日18:32:55
cf 450 B
题意就是让你用循环实现一个类似斐波那契的过程,没啥难度,找规律的题,比hdu1005简单。只有一个地方:对负数取余。比如说,题目的要求是-1%3==2,但c语言实现的输出结果是-1%3==-1。又回去补了一发基础知识。


博弈论:
(Bouton's Theorem):对于一个Nim游戏的局面(a1,a2,...,an),它是P-position当且仅当a1^a2^...^an=0,其中^表示异或(xor)运算。
怎么样,是不是很神奇?我看到它的时候也觉得很神奇,完全没有道理的和异或运算扯上了关系。但这个定理的证明却也不复杂,基本上就是按照两种position的证明来的。


根据定义,证明一种判断position的性质的方法的正确性,只需证明三个命题: 1、这个判断将所有terminal position判为P-position;2、根据这个判断被判为N-position的局面一定可以移动到某个P-position;3、根据这个判断被判为P-position的局面无法移动到某个P-position。


第一个命题显然,terminal position只有一个,就是全0,异或仍然是0。


第二个命题,对于某个局面(a1,a2,...,an),若a1^a2^...^an!=0,一定存在某个合法的移动,将ai改变成ai'后满足a1^a2^...^ai'^...^an=0。不妨设a1^a2^...^an=k,则一定存在某个ai,它的二进制表示在k的最高位上是1(否则k的最高位那个1是怎么得到的)。这时ai^k<ai一定成立。则我们可以将ai改变成ai'=ai^k,此时a1^a2^...^ai'^...^an=a1^a2^...^an^k=0。


第三个命题,对于某个局面(a1,a2,...,an),若a1^a2^...^an=0,一定不存在某个合法的移动,将ai改变成ai'后满足a1^a2^...^ai'^...^an=0。因为异或运算满足消去率,由a1^a2^...^an=a1^a2^...^ai'^...^an可以得到ai=ai'。所以将ai改变成ai'不是一个合法的移动。证毕。


根据这个定理,我们可以在O(n)的时间内判断一个Nim的局面的性质,且如果它是N-position,也可以在O(n)的时间内找到所有的必胜策略。Nim问题就这样基本上完美的解决了。


。。。。。看不懂




vector:比赛的时候看到的,作用就是可以在后面顺次定义新变量;






2017年4月13日16:02:16
int最大值 :0x7fffffff
int最小值 :0x80000000
对递归的一点浅显的理解:
http://blog.****.net/qiujunchao/article/details/4373321
还有形参和实参的概念(基础很重要!)
http://blog.****.net/qq_33187168/article/details/50346465
or
c primer plus P107
但是我还是觉得刘汝佳讲的明白(P65)。


int f(int n){
return n==1 || n==2  ? 1 : f(n-1) + (n-2);
}
斐波那契,没啥说的。想说的是它内存复杂度时间复杂度方面的一些有关问题。
书上说n所占的内存会随程序的结束而释放。但,在运行的时候占用的内存还是要算出来的。
上代码:
#include<stdio.h>
int t = 1;
int f(int a){
    printf("%d\n",t++);
    return a==1||a==2?1:f(a-1)+f(a-2);
}
int main(){
    int i=10;
    int c = f(i);
    printf("\n%d\n",c);
    return 0;
}
输出的是1~109和55,也就是说函数被调用了109次。怎么来的?10要调9,8;9要调8,7,8要调7,6……就是这样的过程:
输入的数 f()调用次数
1        1
1
3
5
9
6 15
...
也是一个递归的过程:
return a==1||a==2?1:f(a-1)+f(a-2)+1;
可以算出来,10的时候就是109;
知道了次数,别的也就好算了:
次数是109,时间复杂度就是o(109),空间复杂度也就是o(109*int);
对不对呢?开任务管理器,发现这个程序占得内存是400k
……根据某个巨巨说是爆栈的问题。。。恩。。。




2017年4月14日18:40:43
dfs初步:八皇后问题  hdu2553
代码:


#include<stdio.h>
#include<string.h>
int ans;
int map[20];
int n;
int jud;


void dfs(int cur){
    if(cur == n){
        ans++;
        return;
    }
    for(int i = 0; i < n; i++){
        jud = 1; map[cur] = i;
        for(int j = 0; j < cur; j++){
            if(map[cur]==map[j]||cur-j==map[cur]-map[j]||cur-j==map[j]-map[cur]){
                jud = 0;
                break;
            }
        }
        if(jud) dfs(cur+1);
    }
}


int main(){
    int a[10];
    for(int i = 1; i <= 10; i++){
        memset(map,0,sizeof(map));
        ans = 0;
        n = i;
        dfs(0);
        a[i-1] = ans;
    }
    while(scanf("%d",&n),n) printf("%d\n",a[n-1]);
    return 0;
}




思路:因为每一列都只会有一个皇后,索性开一个大小为n的数组,第i行第j个位置就是map[i]=j;cur就是当前所在的行数;第一个if的意思是判断cur有没有到n,第一个for是将map[cur]赋值,即在第cur行i列放一个棋子。第二层for循环判断的是是否有相同列和主副对角线;
比如说:   * 1 * 3 * * * *
这样的情况就会在第2组中被舍去。
只有上一行满足条件之后才会进入下一次的递归。






2017年4月17日15:12:55
poj 1321
思路:就是一个八皇后问题。
int jud(int y){
    for(int i = 0; i < n; i++)
        if(map[i][y]=='Q') return 0;
    return 1;
}
void dfs(int cur){
    if(k == 0){
        ans++;
        return;
    }
    if(cur==n)
        return;
    for(int i = 0; i < n; i++){
        if(jud(i)&&map[cur][i]=='#'){
            map[cur][i]='Q';
            k--;
            dfs(cur+1);
            map[cur][i]='#';
            k++;
        }
    }
    dfs(cur+1);
}
cur就是行数,剩下的都是已知。这个算法的优点是占的内存少。
优化的话就用一个数组来记录这一列有没有放棋子,加了一个n的数组,但是时间上能快上好多。




找到一个好玩的网站 http://hzwer.com/


2017年4月18日18:03:08
poj 1426
不用搜索 直接打表,题目水直接long long就能过 超了就用同余模
    a[0] = 1;
    for(int i=0,j=1;j<600000;i++){
        a[j] = a[i]*10;
        j++;
        a[j] = a[i]*10+1;
        j++;
    }
    //printf("%lld",a[599999]);
    for(int i = 1; i <=200; i++){
        for(int j = 0; j < 600000; j++){
            if(!(a[j]%i)){
                b[i] = a[j];
                break;
            }
        }
    }


一个巨巨的博客
http://blog.****.net/v_july_v




2017年4月21日20:52:51
kmp看好几天了,还是看不懂。。。
百无聊赖,随便找了几个水题做做
遇到了一道以前做过的题:hdu1097
就是求a^b的末位数字。巨水,打表题。但是当时我做的特别艰辛:是用switch做的,贼麻烦。不得不说看到了自己的成长,但是这个成长的过程有一点长了。还是要加快速度啊。。。






2017年4月22日21:54:14
今天的比赛真酸爽!哈哈哈哈!
有一个题目特别有意思:问你16进制数有几个洞?
洞?洞!
题解:
8 2
A 1
9 1
5 0
自己体会(手动滑稽)
题不重要,思想很重要:谁告诉你8就是代表伸八个手指头了!!兴许人家就是一二维图形呢!这引发了我一个更有意思的思考:8这个符号究竟代表着什么?是不是给它不同的数学定义,它就会变成另外一种截然不同的意义呢?再想远一点,其他的数字啦,其他的符号啦,不过只是一个方便记录的符号,完全可以有另外的意思。看到8就想到数字定义下的8,这算不算是一种惯性思维呢?在以后我们看到一些熟悉的数字啊,字母啊,公式定理啊,是不是应该看一看它是在哪一种方式下产生的符号呢?
这又令我想到另一个问题 : 1+1=? 不是哥德巴赫猜想那个,而是纯粹的 1+1会等于几呢?它依据的数学模型是什么?1代表的又是什么呢?
脑洞有多大,世界就有多大!




2017年4月25日18:53:03
位运算整理:下面的数都是针对二进制的数
按位取反:~
就是把一个二进制数各位都取反;
比方说 定义一个 unsigned int i = 0;
~i 输出的就是 4294967295 即 0x ffff ffff;
另外,~-1==0,所以while(~scanf())和while(scanf()!=EOF)是相同的
按位与:&
字面意思,一位一位比较,都是1就是1,不然就是0;
例如,a&1就可以判断a是不是奇数啦,是不是很厉害
按位或:|
字面意思,一位一位比较,一个是1就行
按位异或:^
字面意思,一位一位比较,一样是0,不一样是1;
在博弈论里有黑科技哟!
左移:<< 
把整个数左移1位,十进制就是*2咯
带符号右移: >> 
同上,逆运算,就是在高位补0或1
无符号右移: >>>  高位补0




快速幂:
int q_pow(int a,int b){
  int r=1,base=a;
  while(b){
    if(b&1) r*=base;
    base*=base;
    b>>=1;
  }
  return r;
}


2017年4月26日19:51:03
scanf有返回值
while(scanf()!=EOF)实现过程:
int a;
    int s[20]={0};
    aa:
        switch(scanf("%d",&a)){
            case 0: getchar();goto aa;
            case -1:goto bb;
            default:if(a<=9&&a>=0)s[a]++;goto aa;
        }
    bb:
        for(int i = 0; i < 20; i++)
            printf("%d\n",s[i]);








/*使用姿势:
bool next_permutation( iterator start, iterator end );
返回值:如果下一个排列字典序更大,返回true,否则返回false
*/
#include <iostream>
#include <algorithm>
using namespace std;
char s[5]="1234";
int main()
{
    printf("%s\n", s);
    while(next_permutation(s,s+4))
    {
        printf("%s\n", s);
    }
}




矩阵入门:
加法减法,数乘:对应位置操作;

矩阵转置:符号A^T :行列互相交换(以左上角右下角连线为轴,翻转矩阵)



2017年6月6日19:36:31
(a/b)%mod!=(a%mod)/(b%mod)
(a/b)%mod==a%(b*mod)/b%mod




rev(a) = (p-p/a)*rev(p%a)%p

以前写的弱智玩意