共 5 个测试点
每个测试点 20 分
每个测试点限时 1 秒
运行内存上限 512MB
咕咕有两个数字 a,b ,它忘记了 a 的前三位(记除去前三位的 a 为 aa ),但它记得 a 与 b 满足 a≡0(mod b),即 a 是 b 的倍数。
请你帮它求出有多少种满足条件的 a。
注意: a 没有前导 0 。
输入格式
一行两个整数,表示 a 和 b 。
输出格式
一行一个整数,表示有多少种满足条件的 a 。
数据范围与约定
对于前 20% 的数据,保证 b=1。
对于前 40% 的数据,保证 b≤2。
对于 100% 的数据,保证 0≤a≤10^14,0<b≤10^180.
样例输入
0 1
样例输出
900
样例解释
任何整数都是 1 的倍数,故 a 的前三位是 100−999 中任何一种情况都可以满足条件。
思路
签到题,就这一个ac了,计算出a的长度,用pow函数制造出100-999的前缀,一个个的取模
#include
#include
#include
#include
using namespace std;
#define IO ios::sync_with_stdio(0); cin.tie(0);//快读
int main()
{
IO;
long long a,b;
cin>>a>>b;
long long len=0,k=a,ans=0;//十年oi一场空,不开longlong见祖宗
while(k)
{
k/=10;
len++;
}
for(int i=100;i<=999;i++)
{
long long j=i*pow(10,len);//计算出缺少的前缀,一个个的尝试
if((j+a)%b==0)ans++;
}
cout<<ans<<endl;
return 0;
}
共 5 个测试点
每个测试点 20 分
每个测试点限时 1 秒
运行内存上限 512MB
有一个 n∗n 的网格,左下角是 (0,0)右上角是 (n,n) 。
咕咕要从左下角移动到右上角,移动规则如下:
若咕咕位于 (a,b) ,它可以花费 w1 个金币到达 (a,b+1) 或 (a+1,b) 。
若 (a,b) 是一个魔法格点,咕咕既可以选择 1 ,也可以选择花费 w2 个金币到达 (a+1,b+1) 。
咕咕想知道从左下角到达右上角最少需要花费多少个金币,请你帮帮它。
输入格式
第一行四个整数 n,k,w1,w2 。
接下来 k 行,第 i 行两个整数 xi,yi ,表示第 i 个魔法格点的坐标。
输出格式
一行一个整数,表示咕咕最少需要花费多少金币。
数据范围与约定
对于 20% 的数据,保证 n≤3 。
对于另 20% 的数据,保证魔法格点只出现在 (0,0) 到 (n,n) 的对角线上,也就是对于任意的 i∈[1,k] , xi=yi 。
对于 100% 的数据,保证 1≤n,w1,w2≤109,0≤k≤2000,0≤xi,yi<n1 ,魔法格点坐标两两不同。
样例输入
3 2 132 100
0 1
1 2
样例输出
464
样例解释
能让咕咕花费最少的路径如下:
(0,0)→(0,1)→(1,2)→(2,3)→(3,3)
在 (0,1),(1,2) 选择 2 (花费 100 金币) ,在其他格点选择 1 (花费 132 金币)。
思路:
据说是最长上升子序列...菜鸡不会,找了个题解看了看
选择1走一步,花费为w1。选择2走两步,花费为w2。
先考虑只走选择1,则到(x,y)的花费为(x+y)∗w1
(x+y)∗w1。
再考虑可以有选择2,我们要用魔法个点来优化之前的选择,则可以将魔法节点排序,那么就可以保证后面的魔法节点无法走到前面,这就无后效性了。再找子问题:
定义f[i]
f[i]为到达第ii个魔法节点的距离,则有
num=a[i].x+a[i].y−a[j].x−a[j].y−2num=a[i].x+a[i].y−a[j].x−a[j].y−2
f[i]=min(f[i],f[j]+num∗w1+w2)f[i]=min(f[i],f[j]+num∗w1+w2)
代码:
#include
#include
#include
#include
using namespace std;
typedef long long ll;
const int maxn = 2005;
ll f[maxn];
struct Node //结构体
{
int x,y;
}a[maxn];
int cmp(Node a,Node b) {//结构体排序
if(a.x != b.x) return a.x < b.x;
return a.y < b.y;
}
int main()
{
int n,k,w1,w2;
scanf("%d%d%d%d",&n,&k,&w1,&w2);
for(int i = 1;i <= k;i++)
{
scanf("%d%d",&a[i].x,&a[i].y);
}
sort(a + 1,a + 1 + k,cmp);//给魔法节点排个序
a[k + 1].x = n;
a[k + 1].y = n;
k++;
for(int i = 1;i <= k;i++)
{
f[i] = 1ll * w1 * (a[i].x + a[i].y);
}
for(int i = 2;i <= k;i++)
{
for(int j = 1;j < i;j++)
{
if(a[j].x < a[i].x && a[j].y < a[i].y)
{
int num = a[i].x + a[i].y - a[j].x - a[j].y - 2;
f[i] = min(f[i],f[j] + 1ll * num * w1 + w2);
}
}
}
printf("%lld\n",f[k]);
return 0;
}
共 5 个测试点
每个测试点 20 分
每个测试点限时 1 秒
运行内存上限 512MB
给定 k ,你需要生成一个没有重边的有向无环图(点编号 1-n ),使得从 1 到 n 的路径数恰好为 k 。
输入格式
一行两个正整数 k,N,表示要求的路径数和该测试点允许的最大点数(即你生成的图点数不得超过 N )。
输出格式
第一行两个正整数 n,m,表示你生成的图的点数和边数。
接下来 m 行,每行两个正整数 u,v ,表示有一条从 u 到 v 的有向边。
如有多个满足条件的图,输出任意一个。
数据范围与约定
测试点编号 N k
1 =2 =1
2 =4 =3
3 =10^3 ≤500
4−5 =66 <2^64
对于 100% 的数据,满足 0<k<2^64 。
除了前面的要求,你的输出还要满足 1≤m≤10^5和 n>1 。
注意:输出中多余的空格和回车、边的输出顺序不影响得分,但多余的其他字符及不合法的输入会导致不得分。
样例输入
2 1000
样例输出
3 3
1 2
2 3
1 3
样例解释
两条路径分别为:
1→2→3
1→3
代码:
#pragma GCC optimize(2)
#include
#include
#include
#include
#include
#include
using namespace std;
typedef unsigned long long ll;
vector<pair<int,int> >vec;
int main() {
ll n,k;scanf("%llu%llu",&k,&n);
ll tmp = k;
int cnt = 0;
while(tmp) {
cnt++;
tmp /= 2;
}
if(n == 2 && k == 1) {
printf("2 1\n");
printf("1 2\n");
return 0;
} else if(n == 4 && k == 3) {
printf("4 5\n");
printf("1 2\n2 3\n3 4\n1 3\n2 4\n");
return 0;
}
int N = cnt + 2;
for(int i = 2;i <= cnt + 1;i++) {
for(int j = i + 1;j <= cnt + 2;j++) {
vec.push_back({i,j});
}
}
for(int i = 0;i < cnt;i++) {
if((k >> i) & 1) {
int nex = cnt - i + 1;
vec.push_back({1,nex});
}
}
printf("%d %d\n",N,(int)vec.size());
for(int i = 0;i < vec.size();i++) {
printf("%d %d\n",vec[i].first,vec[i].second);
}
return 0;
}