JS
解绑事件
对象.on事件 对象.on事件=null
如果是 addEventListener方式必须使用 对象.removeEventListener () 匿名函数无法解绑
- mouseover和mouseout会有冒泡效果
- mouseenter和mouseleave没有冒泡效果
事件委托:
事件委托是利用事件流的特征解决一些开发需求的知识技巧
原理利用事件冒泡的特点,给父元素注册事件,当我们触发子元素的时候,会冒泡到父元素身上,从而触发父元素的事件。
target属性下面的标签还有一个tagName属性,tagName属性是该标签对应的名称
阻止默认行为:
preventDefault()函数
其他事件
- 页面加载事件
- 加载外部资源(比如图片、外联CSS和JavaScript)加载完毕时触发的事件
当初始的HTML文档被完全加载和解析完成之后,DOMContentLoaded事件会被触发,无需等待样式表、图像等完全加载。
事件名:DOMContentLoaded
元素滚动事件:滚动条在滚动的时候持续发生的事件
srollLeft和srollTop属性 可以获得被滚动的大小
如果需要获得整个页面的scrollTop属性,就是获得html标签对应的滚动条距离,还可以更改这个值,不用带单位
应该这样写:document.documentElement().scrollTop
获取宽高
clientWidth 和 clientHeight 包括padding值不包括border值
元素尺寸于位置
前面所说的滚动距离,都是自己得到的一个确切的值,通过这个可以得到元素在页面中的位置。
获取宽高
获取元素自身的宽高,包含元素自身设置的·宽高、padding、border 使用 offsetWidth 和 offsetHeight
获取位置
获得元素距离自己定位父级元素(必须是带有定位的父级元素)的左、上距离 offsetLeft 和 offsetTop 但是这俩个是只读属性
element.getBoundClientRect() 获得元素的大小以及相对于 视口 的位置 会返回一个对象
实现页面滚动光滑:
html
{
scroll-behavior:smooth;
}
日期对象
实例化
const date = new Date()
一些日期对象方法:
时间戳
是指从1970年1月1号时0时0分0秒到现在的毫秒数,是一种特殊的计量时间的方式
获取时间戳
- getTime()
- +new Date()
- Date.now()
DOM节点
查找节点
- 父节点查找,parentNode属性,返回最近一级的父节点,没有为NULL
- 子节点查找 childNodes 所有节点,返回的是一个伪数组
- 兄弟节点查找,nextElementSibLing 属性 下一个兄弟节点 previousElementSibling 属性 上一个兄弟节点
增加节点
document.creatElement('标签')
追加节点
- 父元素.appendChild(要插入的元素) ——插入到父元素的最后一个子元素
- 父元素.insertBefore(要插入的元素,插入到哪一个元素)——插入到该元素前面
克隆节点
cloneNode(布尔值) true代表克隆后代节点,false代表不克隆后代节点 默认是false
删除节点
父元素.removeChild(要删除的元素) 必须再父元素下删除
M端事件
移动端会有自己独特的一个事件——触屏事件touch
- touchstart 手指触摸到一个DOM元素触发
- touchmove 手指在一个DOM元素上滑动时触发
- touchend 手指从一个DOM元素上移开时触发
题解:
第四次题组 [Cloned] - Virtual Judge (vjudge.net)
1.这个题目的意思是构建一个数组,每一位都要被对应的下标整除,加起来要被n整除。
2.我们从后往前,除了第一位,其他各位都是对应的下标 i ,这样能保证每一位都满足,第一位因为1可以被任何数字整除,所以第一位的数字是n-res%n
#include<stdio.h>
#define Maxsize 210
int main()
{
int t,n,i;
long long res=0;
int a[Maxsize];
scanf("%d",&t);
while(t--)
{
res=0;
scanf("%d",&n);
for(i=n;i>1;i--)
{
a[i]=i;
res+=a[i];
}
a[1]=n-(res%n);
for(i=1;i<=n;i++)
{
printf("%d ",a[i]);
}
puts("");
}
}
第四次题组 [Cloned] - Virtual Judge (vjudge.net)
1.这道题的意思是求出最大的k 要满足 j-i=k 交换i j能够保持顺序
2.因为每一个数字都只有一个,那么我们找到最大需要交换的其实是i对于a[i]的距离,对于每一个a[i] 我们都去求出距离,然后求出最大公约数即可
#include<stdio.h>
#include<math.h>
#define maxsize 200010
int a[maxsize];
int fun(int a,int b)
{
int r;
r=a%b;
while(r)
{
a=b;
b=r;
r=a%b;
}
return b;
}
int main()
{
int t,n,i;
int res;
scanf("%d",&t);
while(t--)
{
res=0;
scanf("%d",&n);
for(i=1;i<=n;i++)
scanf("%d",&a[i]);
for(i=1;i<=n;i++)
{
if(res==0)
{
res=abs(a[i]-i);
}
else if(abs(a[i]-i))
{
res=fun(res,abs(a[i]-i));
}
}
printf("%d\n",res);
}
return 0;
}
第四次题组 [Cloned] - Virtual Judge (vjudge.net)
1.这个题目的意思是交换俩个不相同的字母一次,是否能保证,是一个回文串
2.只需要计算 俩个不同元素的字母个数是否大于等于2即可,当然还要判断是否能构成回文,是否能构成回文很简单,去判断元素的出现的个数,只能有一个是奇数,或者全都是偶数
#include<stdio.h>
#include<string.h>
#define size 60
int main()
{
int t,i,j,flag,res;
char str[size];
scanf("%d",&t);
while(t--)
{
scanf("%s",str);
//小写字母
res=0;
flag=0;
int alp[27]={0},count=0,book[27]={0};
for(i=0;str[i];i++)
{
alp[str[i]-'a']++;
if(alp[str[i]-'a']>=2&&book[str[i]-'a']==0)
{
book[str[i]-'a']=1;
count++;
}
res=res^str[i];
}
if(res==0||(res>='a'&&res<='z'))
{
if(count>=2)
{
puts("YES");
}
else puts("NO");
}
else puts("NO");
}
return 0;
}
第五周任务 [Cloned] - Virtual Judge (vjudge.net)
1.这道题的意思其实就是求组合数,可以先求出杨辉三角
2.利用插空法计算出来
#include<stdio.h>
#define Maxsize 2010
#define mod 1000000007
long long a[Maxsize][Maxsize];
int main()
{
a[0][0]=1;
int i,j;
for(i=1;i<Maxsize;i++)
{
a[i][0]=a[i][i]=1;
for(j=1;j<=i;j++)
{
a[i][j]=(a[i-1][j-1]+a[i-1][j])%mod;
}
}
int n,k,m;
scanf("%d%d",&n,&k);
m=n-k+1;
for(i=1;i<=k;i++)
{
printf("%lld\n",(a[k-1][i-1]*a[m][i])%mod);
}
return 0;
}
第五周任务 [Cloned] - Virtual Judge (vjudge.net)
1.这道题的意思是在?位填入数据,有多少种可能能够满足除以 13余下5
2.暴力+dp,dp每一位的取值能够余下的值,相乘
#include<stdio.h>
#include<string.h>
#define maxSize 1000010
#define mod 1000000007
char str[maxSize];
int dp[maxSize][13];
int main()
{
scanf("%s",str+1);
int i,j,k,t;
int n=strlen(str+1);
if(str[1]=='?')
{
for(i=0;i<=9;i++)
{
dp[1][i]=1;
}
}
else
{
dp[1][str[1]-'0']=1;
}
for(i=2;i<=n;i++)
{
if(str[i]=='?')
{
for(j=0;j<=9;j++)
{
for(k=0;k<=12;k++)
{
t=(k*10+j)%13;
dp[i][t]=(dp[i][t]+dp[i-1][k])%mod;
}
}
}
else
{
for(k=0;k<=12;k++)
{
t=(k*10+(str[i]-'0'))%13;
dp[i][t]=(dp[i][t]+dp[i-1][k])%mod;
}
}
}
printf("%d\n",dp[n][5]);
return 0;
}
第五周任务 [Cloned] - Virtual Judge (vjudge.net)
1.这道题是求 a序列的对于b序列 相差的大小
2.线性代数知识,先求出1-n的阶乘,遍历对于数组,数组的 i 后一位开始遍历 j 有 小于的 就记录下来,拿到n-i对应的阶乘 * j的位置后小于当前 i 的个数,作为结果,这个是康托展开。
3.俩个都康托展开,相减即可。
#include<stdio.h>
#include<math.h>
int a[10],b[10],n;
int c[10]={1};
int solve(int k[])
{
long long res=0;
int i,t=0,j;
for(i=1;i<=n;i++)
{
t=0;
for(j=i+1;j<=n;j++)
{
if(k[j]<k[i]) t++;
}
res+=t*c[n-i];
}
return res;
}
int main()
{
scanf("%d",&n);
int i;
for(i=1;i<=9;i++)
{
c[i]=i*c[i-1];
}
for(i=1;i<=n;i++)
{
scanf("%d",&a[i]);
}
for(i=1;i<=n;i++)
{
scanf("%d",&b[i]);
}
printf("%lld\n",abs(solve(a)-solve(b)));
return 0;
}
第四次题组 [Cloned] - Virtual Judge (vjudge.net)
1.这道题目的意思是,先求出最小生成树,找到最小生成树的最长的那一条边,然后再根据最长的边作为上界,求出最大生成树。
2.需要用到并查集和kruskal算法。
#include<stdio.h>
#include<algorithm>
#define maxN 100010
#define maxM 200010
using namespace std;
int n,m;
int f[maxN];
typedef struct node
{
int u,v,w;
}NODE;
NODE edges[maxM];
bool cmp1(NODE a,NODE b)
{
return a.w<b.w;
}
bool cmp2(NODE a,NODE b)
{
return a.w>b.w;
}
int getfather(int x)
{
if(x==f[x]) return x;
f[x]=getfather(f[x]);
return f[x];
}
int is(int x,int y)
{
int i=getfather(x),j=getfather(y);
if(i!=j)
{
f[i]=j;
return 1;
}
return 0;
}
int main()
{
int i,j,con=0,nox;
long long res=0;
scanf("%d%d",&n,&m);
for(i=1;i<=n;i++)
{
f[i]=i;
}
for(i=0;i<m;i++)
{
scanf("%d%d%d",&edges[i].u,&edges[i].v,&edges[i].w);
}
sort(edges,edges+m,cmp1);
for(i=0;i<m;i++)
{
if(is(edges[i].u,edges[i].v))
{
con++;
if(con==n-1)
{
nox=edges[i].w;
break;
}
}
}
for(i=0;i<=n;i++)
{
f[i]=i;
}
sort(edges,edges+m,cmp2);
int newcnt=0;
for(i=0;i<m;i++)
{
// printf("%d %d %d\n",edges[i].u,edges[i].v,edges[i].w);
if(edges[i].w<=nox&&is(edges[i].u,edges[i].v))
{
// printf("%d %d %d\n",i,edges[i].u,edges[i].v);
res+=edges[i].w;
newcnt++;
if(newcnt==n-1)
{
break;
}
}
}
printf("%lld\n",res);
return 0;
}
第四次题组 [Cloned] - Virtual Judge (vjudge.net)
1.这道题目的意思是,要么选择俩个不相等的下标,a[i]加到a[j] 或者把 a[i] 移除 构成一个有序的数组
2. 有序的数组其实就是变成前面全是0 后面全是1 ,不管做上面哪一种操作都是一样的,因为数组里面只有0 和 1.
3.所以我们只需要排序输出前面对于原数组来说,出现1的位置的次数
#include<stdio.h>
#define maxSize 100010
int a[maxSize];
int main()
{
int t,n,zero=0,one=0,i,res=0;
scanf("%d",&t);
while(t--)
{
zero=one=res=0;
scanf("%d",&n);
for(i=0;i<n;i++)
{
scanf("%d",&a[i]);
if(a[i]) one++;
else zero++;
}
for(i=0;i<zero;i++)
{
if(a[i]==1) res++;
}
printf("%d\n",res);
}
return 0;
}