小A现在站在一个 n n n个人的队伍里排队,他们的编号依次为 1 ∼ n 1 \sim n 1∼n,现在她面前有 m m m个窗口,其中第 i i i 个窗口会给出一个数字 a i a_i ai,然后将队伍中所有编号为 a i a_i ai倍数的人带出队伍,请问最后队伍中还剩下多少个人?
输入格式
第一行两个用空格隔开的整数分别表示 n , m n,m n,m
第二行 m m m个用空格隔开的整数,其中第 i i i个代表 a i a_i ai输出格式
输出一个整数,代表剩下多少个人
数据规模与约定
对于 30 % 30\% 30%的数据, 1 ≤ n ≤ 100 , 1 ≤ m ≤ 10 1 \leq n \leq 100,1 \leq m \leq 10 1≤n≤100,1≤m≤10
对于 60 % 60\% 60%的数据, 1 ≤ n ≤ 1000 , 1 ≤ m ≤ 10 1 \leq n \leq 1000, 1 \leq m \leq 10 1≤n≤1000,1≤m≤10
对于 100 % 100\% 100%的数据, 1 ≤ n ≤ 100000 , 1 ≤ m ≤ 100 , 1 ≤ a i ≤ n 1 \leq n \leq 100000, 1 \leq m \leq 100,1 \leq a_i \leq n 1≤n≤100000,1≤m≤100,1≤ai≤n
循环遍历a数组,标记所有n以内a[i]的倍数,每标记一个结果减一,输出结果即可
#include
#include
#include
#include
using namespace std;
int a[105];
bool out[100005];
int main()
{
int n, m;
scanf("%d%d", &n, &m);
for (int i = 0; i < m; i++)
{
scanf("%d", &a[i]);
}
int ans = n;
for (int i = 0; i < m; i++)
{
for (int j = 1; a[i] * j <= n; j++)
{
if (!out[a[i] * j])
{
out[a[i] * j] = true;
ans--;
}
}
}
printf("%d", ans);
return 0;
}
小B面前有 n n n个开关,开始时第 i i i个开关的状态是 a i a_i ai ,其中 a i = 1 a_i = 1 ai=1 表示第 i i i个开关是开的, a i = 0 a_i = 0 ai=0表示第 i i i个开关是关的。现在小B获得了一种魔法,他可以进行若干次操作,每次操作可以选择一个数 x x x,然后把 x x x号开关及其之前的所有开关状态反转(开变关,关变开),请问小B最少需要多少次操作才能使所有开关都变为关的状态。
输入格式
第一行一个整数表示 n n n
第二行为一个长度为 n n n的 01 01 01符串,即每一位只会是 0 0 0或者 1 1 1输出格式
输出一个整数,表示最少需要多少次操作才能使所有开关都变为关的状态
数据规模与约定
对于 30 % 30\% 30%的数据, 1 ≤ n ≤ 20 1 \leq n \leq 20 1≤n≤20
对于 60 % 60\% 60%的数据, 1 ≤ n ≤ 2000 1 \leq n \leq 2000 1≤n≤2000
对于 100 % 100\% 100%的数据, 1 ≤ n ≤ 200000 1 \leq n \leq 200000 1≤n≤200000
从后往前遍历,遇到1之后把前面的数字反转
为了降低时间复杂度,在遇到1之后不是把前面的数字反转,而是将寻找的目标反转,只需要一次遍历即可得出结果,时间复杂度为O(n)
#include
using namespace std;
int main()
{
int n;
char a[200005];
scanf("%d%s", &n, a);
int goal = 1, ans = 0;
for (int i = n - 1; i >= 0; i--)
{
if (!(a[i] - '0' == goal))
{
goal = 1 - goal;
ans++;
}
}
printf("%d", ans);
return 0;
}
给定两个字符串 S S S和 T T T,它们都只由小写字母组成。现在请计算出字符串 S S S的本质不同的排列中有多少种是字符串 T T T的子串。
本质不同,就是看起来不同,例如aab
有 3 3 3种本质不同的排列aab
,aba
,baa
。输入格式
第一行有一个字符串 S S S
第二行有一个字符串 T T T输出格式
输出一个整数表示字符串 S S S的本质不同的排列中有多少种是字符串 T T T的子串
数据规模与约定
对于 30 % 30\% 30%的数据, 1 ≤ ∣ S ∣ ≤ 5 , 1 ≤ ∣ T ∣ ≤ 200 1 \leq |S| \leq 5, 1 \leq |T| \leq 200 1≤∣S∣≤5,1≤∣T∣≤200
对于 60 % 60\% 60%的数据, 1 ≤ ∣ S ∣ ≤ 2000 , 1 ≤ ∣ T ∣ ≤ 2000 1 \leq |S| \leq 2000, 1 \leq |T| \leq 2000 1≤∣S∣≤2000,1≤∣T∣≤2000
对于 100 % 100\% 100%的数据, 1 ≤ ∣ S ∣ ≤ 200000 , 1 ≤ ∣ T ∣ ≤ 200000 1 \leq |S| \leq 200000,1 \leq |T| \leq 200000 1≤∣S∣≤200000,1≤∣T∣≤200000
此题本人赛上只拿到 30分(菜是原罪)
暴力解法,循环遍历 S S S的每个排列,判断 S S S是否是 T T T的子串
待我有了好的思路,再更新新的代码
2020.7.28
更新了90分代码和满分做法的思路
90分的方法是,用滑动窗口卡子串
如果窗口中的子串与 S S S串中字符的个数和种类均相同
则为 S S S的一个排列,放入set去重,最后输出集合的大小即可
评测机不支持C++11的unordered_map和unordered_set
同时记录 [ l , r ) [ l, r ) [l,r)的字符串tmp也要消耗一定的时间,最后一个测试点超时
说一下满分的思路(结合参考了各路神仙的方法)
将set字符串去重改成字符串哈希,用vector存储 后面去重
tmp字符串计算改成用longlong计算类似前缀和的操作
能够拿到满分
哈希用的不熟,系统关了,也懒得写了,可以去看其他人的博客
#include
#include
#include
#include
#include
#include
#include
using namespace std;
bool IsSubStr(string t, int start, string s);
int main()
{
long long ans = 0;
string s, t;
getline(cin, s);
getline(cin, t);
sort(s.begin(), s.end());
do
{
for (int i = 0; i < t.size(); i++)
{
if (t[i] == s[0] && IsSubStr(t, i, s))
{
ans++;
break;
}
}
} while (next_permutation(s.begin(), s.end()));
printf("%lld", ans);
return 0;
}
bool IsSubStr(string t, int start, string s)
{
for (int i = 0; i < s.size(); i++)
{
if (s[i] != t[i + start])
{
return false;
}
}
return true;
}
#include
#include
#include
#include
#include
#include
#include
using namespace std;
string s, t;
set<string> ss;
map<char, int> need;
int main()
{
cin >> s >> t;
// S只有一个字符时 可以单独拿出来判断
if (s.size() == 1)
{
bool find = 0;
for (int i = 0; i < t.size(); i++)
{
if (t[i] == s[0])
{
find = true;
break;
}
}
printf(find ? "1\n" : "0\n");
return 0;
}
for (int i = 0; i < s.size(); i++)
need[s[i]]++;
int l = 0, r = 0;
while (r < t.size())
{
if (!need.count(t[r]) || !need[t[r]])
{
while (l < r && t[l] != t[r])
{
need[t[l]]++;
l++;
}
l++;
}
else
{
need[t[r]]--;
}
if (need.count(t[r]) && !need[t[r]] && (r - l + 1) == s.size())
{
string tmp = "";
for (int i = l; i < r; i++)
{
tmp += s[i];
}
ss.insert(tmp);
}
r++;
}
printf("%d\n", ss.size());
return 0;
}