2小时,5道编程题
删除链表的第K个元素,输出删除后的链表。n个元素,n<=1E6, 1<=k<=n
送分题
#include
using namespace std;
const int N = 1e6+100;
int a[N];
int main(void) {
int n,x;
cin>>n>>x;
for(int i=1;i<=n;++i)
scanf("%d",a+i);
for(int i=1;i<=n;++i) {
if(i==x) continue;
printf("%d%c",a[i],i==n?'\n':' ');
}
return 0;
}
100%
长度不超过5000的字符串S,输出所有不相同的子串字典序第K小的。如aabb, k =3, a,aa,aab,aabb,ab,abb,b,bb
, 答案为abb
(1<=k<=5)
一开始用map暴力存储所有子串,然后auto遍历得到第k个,内存超限,只过了40%,后来换成最大堆,每次只存1000个,不判重(觉得1000个重复的里面应该有前5个吧), 然后TLE,改成100个就WA,反正都是40%左右
然后想到要不用字典树吧,所有的子串都插入到字典树中,然后线序遍历,得到第K个,不知道为什么只过了90%的数据
#include
using namespace std;
char str[5000+100];
struct Trie{
int son[2000000][26];
int cnt,root;
int getOne() {
memset(son[cnt],-1,sizeof(son[cnt]));
return cnt++;
}
void init() {
cnt = 0;
root = getOne();
}
void insert(char * s,int st,int ed) {
int now = root;
for(int i=st;i<=ed;++i) {
int index = s[i]-'a';
if(son[now][index]==-1) {
son[now][index] = getOne();
}
now = son[now][index];
}
}
void dfs(int& k,int now,string ss) {
if(--k==0) {
cout<<ss<<endl;
exit(0);
}
for(int i=0;i<26;++i) {
if(son[now][i]!=-1) {
dfs(k,son[now][i],ss+(char)('a'+i));
}
}
}
}tree;
int main(void) {
int k;
cin>>str>>k;
++k;
tree.init();
int len = strlen(str);
for(int i=0;i<len;++i) {
tree.insert(str,i,len-1);
}
string sss;
tree.dfs(k,tree.root,sss);
return 0;
}
90%
把n拆成a+b(a,b>=0), 使得a,b的所有数位之和最大。n<=1E12,T组输出,T<=100
#include
using namespace std;
int S(long long x) {
int ans = 0;
while(x>0) {
ans += x%10;x/=10;
}
return ans;
}
int main(void) {
long long n;
int T;
cin>>T;
while(T--) {
scanf("%lld",&n);
if(n<=9) {
printf("%lld\n",n);continue;
}
long long x = 9;
while(x*10+9<=n) {
x = x*10+9;
}
n-=x;
printf("%d\n",S(x)+S(n));
}
return 0;
}
100%
n个模板并排放置,宽度都为1,长度为hi, (n<=5000, hi<=1E9),每次可以横着刷或者竖着刷,刷一次不能有断层
5
2 2 1 2 1
3
2 2
2
暂时没什么好的思路,如果都是竖着刷,那么要刷n次,所以答案一定<=n, 直接输出n可以对55%…
是dp吗?
给一个长度不超过400的字符串,1E5个询问 ,每次询问一个区间的子串最少可以切分分成几个回文子串
ababa 4
1 4
1 5
2 5
1 3
2
1
2
1
先dp处理出所有区间是否是回文子串,然后处理出以每个位置为起点,可以为回文子串的终点,存到vector数组中。然后贪心匹配。
只通过了20%…
#include
using namespace std;
char s[500+10];
vector<int> v[510];
int dp[510][510];//每个区间是否回文
int main(void) {
int Q,L,R,len;
scanf("%s",s+1);
scanf("%d",&Q);
len = strlen(s+1);
for(int i=1;i<=len;++i)
v[i].push_back(i),dp[i][i]=1;
for(int i=1;i<len;++i) {
if(s[i]==s[i+1]) dp[i][i+1] = 1,v[i].push_back(i+1);
}
for(int lenth=3;lenth<=len;++lenth) {
for(int left=1;left+lenth-1<=len;++left) {
int right = left+lenth-1;
if(s[left]==s[right]&&dp[left+1][right-1] == 1)
dp[left][right]=1, v[left].push_back(right);
}
}
while(Q--) {
scanf("%d%d",&L,&R);
int ans = 0;
int x = L;
while(1) {
int id = upper_bound(v[x].begin(),v[x].end(),R)-v[x].begin()-1;
x = v[x][id]+1;
++ans;
if(x==R+1) break;
}
printf("%d\n",ans);
}
return 0;
}
2020.8.23 23:37
xzc