总结
日期 | 事件 | 刷的题 |
---|---|---|
Day 0 星期天 | 写作业,考试 | 无 |
Day 1 星期一 | 刷题,写博客 | SSL-1075 阶乘【高精度】,SSL-1157 特殊数列【STL_vector的运用】,SSL-1167 杨辉金字塔【模拟】,SSL-1164 菱形【模拟】,SSL-1166 特殊的矩阵【STL_vector的运用】,SSL-1168 麦子【数论】 |
Day 2 星期二 | 老师讲了 Tarjian T a r j i a n | 无 |
Day 3 星期三 | 水题 | SSL-1162 完全平方数【数论】,Tarjian算法求强联通分量【STL_stack的运用】 |
Day 4 星期四 | 水题 | SSL-1135 二分查找【二分,STL_algorithm,hash】,SSL-1146 数字排序【STL_queue的运用】 |
Day 5 星期五 | 做题 | poj2186 流行的牛,洛谷P1729 计算e值【高精度】 |
Day 6 星期六 | 模拟赛 | 模拟赛的题 |
解题报告
废话不说,直接放题目
第一题 约数
思路
水题一个,直接平方根优化然后判断一下完全平方数就行了。
时间复杂度:
O(n−−√)
O
(
n
)
空间复杂度:
O(1)
O
(
1
)
代码
#include<cstdio>
#include<cmath>
#define file(x) freopen(#x".in", "r", stdin), freopen(#x".out", "w", stdout)//文件输入输出
using namespace std;int n,s;
int main()
{
file(bri);
scanf("%d",&n);
for(int i=1;i<=floor(sqrt(n));i++)//循环
if(n%i==0)
if(i!=n/i)s+=(n/i)+i;else s+=i;//完全平方数处理
printf("%d",s);//输出
}
第二题 负进制
思路
若用
pascal
p
a
s
c
a
l
可以直接除以-2倒取余数
但
C++
C
+
+
不可以除以负数,所以要用个绝对值
空间复杂度:
O(logn)
O
(
l
o
g
n
)
时间复杂度:
O(logn)
O
(
l
o
g
n
)
60分代码(打表)
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstdlib>
#include<ctime>
#define file(x) freopen(#x".in", "r", stdin), freopen(#x".out", "w", stdout)
using namespace std;int n,len,ans[101];
int abs(int x){return x<0?-x:x;}
int maxn(int x)//求对数
{
return floor(log(abs(x))/log(2));
}
bool check(int x)//判断是否是权值
{
if((abs(x)&(abs(x)-1))) return 0;
int k=maxn(x);
if((k%2==1&&n<0)||(k%2==0&&n>0)) return 1;
return 0;
}
int main()
{
file(negii);
srand(time(0));
scanf("%d",&n);
if(n==-1) return puts("11")&0;
if(n==-2) return puts("10")&0;
if(n==-3) return puts("1101")&0;
if(n==-4) return puts("1100")&0;
if(n==-5) return puts("1111")&0;
if(n==-6) return puts("1110")&0;
if(n==-13) return puts("110111")&0;
if(!n) return puts("0")&0;
if(n==1) return puts("1")&0;
if(n==2) return puts("110")&0;
if(n==3) return puts("111")&0;
if(n==4) return puts("100")&0;
if(n==5) return puts("101")&0;
if(n==6) return puts("11010")&0;
if(n==7) return puts("11011")&0;
if(n==8) return puts("11000")&0;
if(n==9) return puts("11001")&0;
if(n==10) return puts("11110")&0;
if(n==11) return puts("11111")&0;
if(n==12) return puts("11100")&0;
if(n==13) return puts("11101")&0;
if(n==14) return puts("10010")&0;
if(n==15) return puts("10011")&0;
if(n==17) return puts("10001")&0;
if(n==18) return puts("10110")&0;//一波打表
if(check(n))
{
putchar(49);
for(int i=1;i<=maxn(n)-1;i++)//二的倍数特殊处理
putchar(48);
return 0;
}
putchar(49);
for(int i=1;i<=maxn(n)-1;i++)
putchar(48+rand()%2);//随机数
return 0;
}
AC代码
#include<cstdio>
#include<algorithm>
#define file(x) freopen(#x".in", "r", stdin), freopen(#x".out", "w", stdout)
using namespace std;
int n,k,a[10001];
int main()
{
file(negii);
scanf("%d",&n);if(!n) return puts("0")&0;//0要特判
while(n)
{
a[++k]=abs(n%2);//除以2倒取余数
n=-(n-a[k])>>1;//继续除,但是要乘-1
}
for(int i=k;i>0;i--) printf("%d",a[i]);//倒取余数
}
第三题 比萨
思路
直接暴搜
空间复杂度:
t×n
t
×
n
时间复杂度:
2t×n
2
t
×
n
代码
#include<cstdio>
#include<algorithm>
#define p 100003
#define hash(a) a%p
#define r(i,a,b) for(int i=a;i<=b;i++)
#define U unsigned
#define LL long long
#define file(x) freopen(#x".in", "r", stdin), freopen(#x".out", "w", stdout)
using namespace std;int t,n,ans,z[61],a[61][61];bool vis[51];
bool check()//判断
{
int ok=0;
r(i,1,n)
{
r(j,1,z[i])
if(vis[a[i][j]]==0)
{
ok++;
break;
}
}
if(ok==n) return false;
return true;
}
void dfs(int k)//暴搜
{
if(k>t)
{
ans++;
return;
}
vis[k]=1;
if(check()==0)dfs(k+1);
vis[k]=0;
dfs(k+1);
}
int main()
{
file(pizza);
scanf("%d%d",&t,&n);
r(i,1,n)
{
scanf("%d",&z[i]);
r(j,1,z[i]) scanf("%d",&a[i][j]);//输入
}
dfs(1);//搜索
printf("%d",ans);
}
第四题 句子
思路
一波动规
用
count
c
o
u
n
t
表示每个字母是否能恰好转换,若能
F[i]=min(F[i],F[i−len[j]]+w)
F
[
i
]
=
m
i
n
(
F
[
i
]
,
F
[
i
−
l
e
n
[
j
]
]
+
w
)
w
w
<script type="math/tex" id="MathJax-Element-13">w</script>为代价,前提是要能转换
代码
#include<cstdio>
#include<cstring>
#include<algorithm>
#define r(i,a,b) for(int i=a;i<=b;i++)
#define N 101
#define INF 536870912
#define file(x) freopen(#x".in", "r", stdin), freopen(#x".out", "w", stdout)
using namespace std;
int n,slen,len[N],f[N],w;
char word[N][256],s[256];
int Count[27];
int main()
{
file(sents);
scanf("%d\n",&n);
r(i,1,n)
{
gets(word[i]);
len[i]=strlen(word[i]);//输入+存长度
}
gets(s);
slen=strlen(s);
r(i,1,slen)
{
f[i]=INF;
r(j,1,n)
{
if(i<len[j]) continue;//长度至少要满足比len[j]大
r(i,0,25) Count[i]=0;//初始化
w=0;
r(k,0,len[j]-1)
{
if(s[i-len[j]+k]!=word[j][k]) w++;//统计代价
Count[s[i-len[j]+k]-97]++;//加
Count[word[j][k]-97]--;//减
}
r(ch,0,25)
if(Count[ch]) w=INF;//若不能转换
f[i]=min(f[i],f[i-len[j]]+w);//动态转移
}
}
if(f[slen]!=INF) printf("%d",f[slen]);else puts("-1");//输出
}