C题 蛇形填数
答案:
761
代码:
简洁
#include<iostream> #include<stdio.h> #include<string.h> using namespace std; const int maxn = 50; int a[maxn][maxn]; int main(){ int k=1; memset(a,0,sizeof(a)); int cnt=1; while(k<=50){ if(k%2==1){ for(int x =k,y=1;x>=1;x--,y++){ a[x][y] = cnt++; } } else{ for(int x=1,y=k;y>=1;x++,y--){ a[x][y] =cnt++; } } k++; } cout<<a[20][20]<<endl; return 0; }
E题 七段码
思路:
并查集+bfs
return :强行终止函数继续运行下去
答案:
80
代码:
#include<iostream> #include<stdio.h> #include<string.h> using namespace std; const int maxn = 25; int map[maxn][maxn]; int ans = 0; int visit[maxn]; int father[maxn]; void init(){ // a b c d e f g // 1 2 3 4 5 6 7 memset(map,0,sizeof(map)); map[1][2] = map[1][6] = 1; map[2][7] = map[2][3] = 1; map[3][4] = map[3][7] = 1; map[4][5] = 1; map[5][6] = map[5][7] = 1; map[6][7] = 1; } int find(int x){//并查集路径压缩 if(father[x]==x) return x; else{ father[x] = find(father[x]); return father[x]; } } void dfs(int d){ if(d>7){ for(int i=1;i<=7;i++) father[i] = i; for(int i=1;i<=7;i++){ for(int j=1;j<=7;j++){ if(visit[i]&&visit[j]&&map[i][j]){ int fx = find(i),fy = find(j); if(fx!=fy){ father[fx] = fy; } } } } int k=0; for(int i=1;i<=7;i++) if(visit[i]&&father[i]==i) k++; if(k==1) ans++; return ;//这里必须要 } visit[d]=1; dfs(d+1); visit[d]=0; dfs(d+1); } int main(){ init(); dfs(1); cout<<ans<<endl; return 0; }
H 子串分值
思路:
代码:
#include<iostream> #include<stdio.h> #include<algorithm> #include<string.h> using namespace std; const int maxn = 2e5+10; typedef long long ll; char a[maxn]; int id[27][maxn],nu[27],b[27]; ll ans; int main(){ cin>>(a+1); int len = strlen(a+1); for(int i=1;i<=len;i++){ id[a[i]-'a'][++nu[a[i]-'a']] = i; } for(int i=1;i<=len;i++){//计算以i开头的子串的贡献 int top = 0; for(int j=0;j<=25;j++){//记录每个字母最快出现在i之后的下标 if(id[j][nu[j]]>=i){ int index = lower_bound(id[j],id[j]+nu[j]+1,i)-id[j]; b[++top] = id[j][index]; } } sort(b+1,b+top+1); int last = i; for(int j=2;j<=top;j++){ ans+=(b[j]-last)*(j-1); last = b[j]; } ans+=(len-last+1)*top; } cout<<ans<<endl; return 0; }
I 平面切分
set去重
思路:
思路:
在同一平面内,如果添加的每一条直线互不相交,则每添加一条直线,就会增加一个平面;当添加一条直线时,这条直线与当前平面内已有直线每产生一个不同位置的交点时,这条直线对平面总数量的贡献会额外增多一个,记为Si,则Si的值为经过这条直线的点+1,1为直线自身贡献的平面,结果为每一条直线的贡献加上最开始的一个平面,结果为S1到Sk的和,k为所有不重合直线的数量,再加上1.
所以我们可以在每添加一条直线时设置一个空的set,将直线与当前平面内其他直线的交点的xy坐标存入set中,如果这一条直线不是重边,则这条直线的贡献为set.size()+1,即ans为所有直线的贡献加上原来的一个平面.
时间复杂度:O(n2*log2n)
代码:
#include<iostream> #include<stdio.h> #include<set> using namespace std; typedef long long ll; pair<double,double>p; bool st[1010]; double s[1010][2]; ll ans; int main(){ int n; cin>>n; for(int i=0;i<n;i++){ cin>>s[i][0]>>s[i][1]; set<pair<double,double> >t; for(int j=0;j<i;j++){ if(st[i]) continue; if(s[i][0]==s[j][0]){ if(s[i][1]==s[j][1]){ st[i] = true; break; } else continue; } p.first = (s[j][1]-s[i][1])/(s[i][0]-s[j][0]); p.second = (s[j][1]*s[i][0]-s[i][1]*s[j][0])/(s[i][0]-s[j][0]); t.insert(p); } if(!st[i]) ans+=t.size()+1; } cout<<ans+1<<endl; return 0; }