1.虢莔薅参加运动会
解法:1^2+2^2+3^2+...n^2=n*(n+1)*(2*n+1)/6代入求解,注意6的逆元求法
题目类型:数论裸题
#include
#define ll long long
using namespace std;
ll n,p;
ll pow_mod(ll a,ll x,ll p)
{
ll tmp=a%p,ans=1;
while(x>=1)
{
if(x%2==1)
ans=ans*tmp%p;
tmp=tmp*tmp%p;
x>>=1;
}
return ans;
}
ll inv(ll a,ll p)
{
ll ans=1;
ans=pow_mod(a,p-2,p);
return ans;
}
int main()
{
while(scanf("%lld%lld",&n,&p)!=EOF)//1^2+2^2+3^2+...n^2=n*(n+1)*(2*n+1)/6代入求解,注意6的逆元
{
ll INV=inv(6,p);
//printf("--%lld\n",INV);
ll res=n%p*(n+1)%p*(2*n+1)%p*INV%p;
printf("%lld\n",res);
}
return 0;
}
2.统计相似字符串
题意:统计含有完全相同的字符的字符串,并输出
解法:map< string , queue
#include
#define ll long long
using namespace std;
int n;
string s[6005],c;
int main()
{
while(scanf("%d",&n)!=EOF)
{
queue q;
map > m;
for(int i=0;i>s[i];
c=s[i];
sort(c.begin(),c.end());
m[c].push(s[i]);
q.push(c);
}
while(!q.empty())
{
int flag=0;
string ts=q.front();
q.pop();
while(!m[ts].empty())
{
if(flag)cout<<" ";
cout << m[ts].front();
m[ts].pop();
flag=1;
}
if(flag)
cout<
3.V8与女友
题目类型:最短路
解法:求出最短路,乘2
(顺便存个SPFA模板):
#include
#include
#include
#include
#define M 100010
#define N 20010
#define INF 1e9
//spfa模板
using namespace std;
int v[M], u[M], w[M], first[N], nex[M];
queue q;
int n, m, s, t, edge_num;
int d[N], inq[N];
void addedge(int x, int y, int z)
{
int &e = edge_num;
u[e] = x; v[e] = y; w[e] = z;
nex[e] = first[u[e]];
first[u[e]] = e;
e++;
u[e] = y; v[e] = x; w[e] = z;
nex[e] = first[u[e]];
first[u[e]] = e;
e++;
}
int SPFA(int a, int b)
{
for (int i = 0; i < n; i++) d[i] = (i == a) ? 0 : INF;
memset(inq, 0, sizeof(inq));
q.push(a); inq[a] = true;
while (!q.empty()) {
int x = q.front(); q.pop();
inq[x] = false;
for (int e = first[x]; e != -1; e = nex[e]) if (d[v[e]] > d[x] + w[e]) {
d[v[e]] = d[x] + w[e];
if (!inq[v[e]]) {
inq[v[e]] = true;
q.push(v[e]);
}
}
}
return d[b];
}
int main()
{
int tests;
int d = 0;
scanf("%d", &tests);
while (tests--) {
d++;
edge_num = 0;
memset(first, -1, sizeof(first));
scanf("%d",&m);
n=10003;//节点数
for (int i = 0; i < m; i++) {
int x, y, z;
scanf("%d%d%d", &x, &y, &z);
addedge(x, y, z);
}
scanf("%d%d",&s,&t);
int ans = SPFA(s,t);
printf("%d\n", 2*ans);
}
return 0;
}
4.大红数星星(学习了大佬题解做法)
题意:无向图判断三元环数目;
解法:枚举一条边,判断左右端点的邻集,顺序去重
#include
#define ll long long
using namespace std;
vector G[100001];
int u[100001],v[100001];
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
int n,m;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
{
G[i].clear();
}
for(int i=1;i<=m;i++)
{
scanf("%d%d",&u[i],&v[i]);
if(u[i]>v[i])swap(u[i],v[i]);
G[u[i]].push_back(v[i]);
}
for(int i=1;i<=n;i++)
{
sort(G[i].begin(),G[i].end());
}
ll ans=0;
for(int i=1;i<=m;i++)
{
vector::iterator iu=G[u[i]].begin(),iv=G[v[i]].begin();
for(;iu!=G[u[i]].end();iu++)
{
while(iv!=G[v[i]].end()&&*iv<*iu)
iv++;
if(iv==G[v[i]].end())
break;
if(*iv==*iu)
ans++;
}
}
cout << ans<< endl;
}
return 0;
}